authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2024-08-26 23:37:03-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2024-08-27 02:09:59-04:00
log8c3f6c72c07e853e28cf7226a3f76da2fd5a9c6e
treeed2f9f0159760dac8deb2dee7f546cc9929f448c
parent93cb44c80582dd02b63b02e7bb7e54d7ad8a4ebc

Dwarf: fix and test string format


8 files changed, 193 insertions(+), 64 deletions(-)

ci/x86_64-linux-debug.sh+1-1
...@@ -64,7 +64,7 @@ stage3-debug/bin/zig build \...@@ -64,7 +64,7 @@ stage3-debug/bin/zig build \
6464
65stage3-debug/bin/zig build test docs \65stage3-debug/bin/zig build test docs \
66 --maxrss 21000000000 \66 --maxrss 21000000000 \
67 -Dlldb=$HOME/deps/lldb-zig/Debug-62538077d/bin/lldb \67 -Dlldb=$HOME/deps/lldb-zig/Debug-70b8227f1/bin/lldb \
68 -fqemu \68 -fqemu \
69 -fwasmtime \69 -fwasmtime \
70 -Dstatic-llvm \70 -Dstatic-llvm \
ci/x86_64-linux-release.sh+1-1
...@@ -64,7 +64,7 @@ stage3-release/bin/zig build \...@@ -64,7 +64,7 @@ stage3-release/bin/zig build \
6464
65stage3-release/bin/zig build test docs \65stage3-release/bin/zig build test docs \
66 --maxrss 21000000000 \66 --maxrss 21000000000 \
67 -Dlldb=$HOME/deps/lldb-zig/Release-62538077d/bin/lldb \67 -Dlldb=$HOME/deps/lldb-zig/Release-70b8227f1/bin/lldb \
68 -fqemu \68 -fqemu \
69 -fwasmtime \69 -fwasmtime \
70 -Dstatic-llvm \70 -Dstatic-llvm \
src/Value.zig+23-41
...@@ -192,11 +192,12 @@ pub fn toBigIntAdvanced(...@@ -192,11 +192,12 @@ pub fn toBigIntAdvanced(
192 zcu: *Zcu,192 zcu: *Zcu,
193 tid: strat.Tid(),193 tid: strat.Tid(),
194) Zcu.CompileError!BigIntConst {194) Zcu.CompileError!BigIntConst {
195 const ip = &zcu.intern_pool;
195 return switch (val.toIntern()) {196 return switch (val.toIntern()) {
196 .bool_false => BigIntMutable.init(&space.limbs, 0).toConst(),197 .bool_false => BigIntMutable.init(&space.limbs, 0).toConst(),
197 .bool_true => BigIntMutable.init(&space.limbs, 1).toConst(),198 .bool_true => BigIntMutable.init(&space.limbs, 1).toConst(),
198 .null_value => BigIntMutable.init(&space.limbs, 0).toConst(),199 .null_value => BigIntMutable.init(&space.limbs, 0).toConst(),
199 else => switch (zcu.intern_pool.indexToKey(val.toIntern())) {200 else => switch (ip.indexToKey(val.toIntern())) {
200 .int => |int| switch (int.storage) {201 .int => |int| switch (int.storage) {
201 .u64, .i64, .big_int => int.storage.toBigInt(space),202 .u64, .i64, .big_int => int.storage.toBigInt(space),
202 .lazy_align, .lazy_size => |ty| {203 .lazy_align, .lazy_size => |ty| {
...@@ -214,6 +215,7 @@ pub fn toBigIntAdvanced(...@@ -214,6 +215,7 @@ pub fn toBigIntAdvanced(
214 &space.limbs,215 &space.limbs,
215 (try val.getUnsignedIntInner(strat, zcu, tid)).?,216 (try val.getUnsignedIntInner(strat, zcu, tid)).?,
216 ).toConst(),217 ).toConst(),
218 .err => |err| BigIntMutable.init(&space.limbs, ip.getErrorValueIfExists(err.name).?).toConst(),
217 else => unreachable,219 else => unreachable,
218 },220 },
219 };221 };
...@@ -326,15 +328,11 @@ pub fn toBool(val: Value) bool {...@@ -326,15 +328,11 @@ pub fn toBool(val: Value) bool {
326 };328 };
327}329}
328330
329fn ptrHasIntAddr(val: Value, zcu: *Zcu) bool {
330 return zcu.intern_pool.getBackingAddrTag(val.toIntern()).? == .int;
331}
332
333/// Write a Value's contents to `buffer`.331/// Write a Value's contents to `buffer`.
334///332///
335/// Asserts that buffer.len >= ty.abiSize(). The buffer is allowed to extend past333/// Asserts that buffer.len >= ty.abiSize(). The buffer is allowed to extend past
336/// the end of the value in memory.334/// the end of the value in memory.
337pub fn writeToMemory(val: Value, ty: Type, pt: Zcu.PerThread, buffer: []u8) error{335pub fn writeToMemory(val: Value, pt: Zcu.PerThread, buffer: []u8) error{
338 ReinterpretDeclRef,336 ReinterpretDeclRef,
339 IllDefinedMemoryLayout,337 IllDefinedMemoryLayout,
340 Unimplemented,338 Unimplemented,
...@@ -343,19 +341,25 @@ pub fn writeToMemory(val: Value, ty: Type, pt: Zcu.PerThread, buffer: []u8) erro...@@ -343,19 +341,25 @@ pub fn writeToMemory(val: Value, ty: Type, pt: Zcu.PerThread, buffer: []u8) erro
343 const zcu = pt.zcu;341 const zcu = pt.zcu;
344 const target = zcu.getTarget();342 const target = zcu.getTarget();
345 const endian = target.cpu.arch.endian();343 const endian = target.cpu.arch.endian();
344 const ip = &zcu.intern_pool;
345 const ty = val.typeOf(zcu);
346 if (val.isUndef(zcu)) {346 if (val.isUndef(zcu)) {
347 const size: usize = @intCast(ty.abiSize(zcu));347 const size: usize = @intCast(ty.abiSize(zcu));
348 @memset(buffer[0..size], 0xaa);348 @memset(buffer[0..size], 0xaa);
349 return;349 return;
350 }350 }
351 const ip = &zcu.intern_pool;
352 switch (ty.zigTypeTag(zcu)) {351 switch (ty.zigTypeTag(zcu)) {
353 .Void => {},352 .Void => {},
354 .Bool => {353 .Bool => {
355 buffer[0] = @intFromBool(val.toBool());354 buffer[0] = @intFromBool(val.toBool());
356 },355 },
357 .Int, .Enum => {356 .Int, .Enum, .ErrorSet, .Pointer => |tag| {
358 const int_info = ty.intInfo(zcu);357 const int_ty = if (tag == .Pointer) int_ty: {
358 if (ty.isSlice(zcu)) return error.IllDefinedMemoryLayout;
359 if (ip.getBackingAddrTag(val.toIntern()).? != .int) return error.ReinterpretDeclRef;
360 break :int_ty Type.usize;
361 } else ty;
362 const int_info = int_ty.intInfo(zcu);
359 const bits = int_info.bits;363 const bits = int_info.bits;
360 const byte_count: u16 = @intCast((@as(u17, bits) + 7) / 8);364 const byte_count: u16 = @intCast((@as(u17, bits) + 7) / 8);
361365
...@@ -379,7 +383,7 @@ pub fn writeToMemory(val: Value, ty: Type, pt: Zcu.PerThread, buffer: []u8) erro...@@ -379,7 +383,7 @@ pub fn writeToMemory(val: Value, ty: Type, pt: Zcu.PerThread, buffer: []u8) erro
379 var buf_off: usize = 0;383 var buf_off: usize = 0;
380 while (elem_i < len) : (elem_i += 1) {384 while (elem_i < len) : (elem_i += 1) {
381 const elem_val = try val.elemValue(pt, elem_i);385 const elem_val = try val.elemValue(pt, elem_i);
382 try elem_val.writeToMemory(elem_ty, pt, buffer[buf_off..]);386 try elem_val.writeToMemory(pt, buffer[buf_off..]);
383 buf_off += elem_size;387 buf_off += elem_size;
384 }388 }
385 },389 },
...@@ -403,8 +407,7 @@ pub fn writeToMemory(val: Value, ty: Type, pt: Zcu.PerThread, buffer: []u8) erro...@@ -403,8 +407,7 @@ pub fn writeToMemory(val: Value, ty: Type, pt: Zcu.PerThread, buffer: []u8) erro
403 .elems => |elems| elems[field_index],407 .elems => |elems| elems[field_index],
404 .repeated_elem => |elem| elem,408 .repeated_elem => |elem| elem,
405 });409 });
406 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]);410 try writeToMemory(field_val, pt, buffer[off..]);
407 try writeToMemory(field_val, field_ty, pt, buffer[off..]);
408 },411 },
409 .@"packed" => {412 .@"packed" => {
410 const byte_count = (@as(usize, @intCast(ty.bitSize(zcu))) + 7) / 8;413 const byte_count = (@as(usize, @intCast(ty.bitSize(zcu))) + 7) / 8;
...@@ -412,22 +415,6 @@ pub fn writeToMemory(val: Value, ty: Type, pt: Zcu.PerThread, buffer: []u8) erro...@@ -412,22 +415,6 @@ pub fn writeToMemory(val: Value, ty: Type, pt: Zcu.PerThread, buffer: []u8) erro
412 },415 },
413 }416 }
414 },417 },
415 .ErrorSet => {
416 const bits = zcu.errorSetBits();
417 const byte_count: u16 = @intCast((@as(u17, bits) + 7) / 8);
418
419 const name = switch (ip.indexToKey(val.toIntern())) {
420 .err => |err| err.name,
421 .error_union => |error_union| error_union.val.err_name,
422 else => unreachable,
423 };
424 var bigint_buffer: BigIntSpace = undefined;
425 const bigint = BigIntMutable.init(
426 &bigint_buffer.limbs,
427 ip.getErrorValueIfExists(name).?,
428 ).toConst();
429 bigint.writeTwosComplement(buffer[0..byte_count], endian);
430 },
431 .Union => switch (ty.containerLayout(zcu)) {418 .Union => switch (ty.containerLayout(zcu)) {
432 .auto => return error.IllDefinedMemoryLayout, // Sema is supposed to have emitted a compile error already419 .auto => return error.IllDefinedMemoryLayout, // Sema is supposed to have emitted a compile error already
433 .@"extern" => {420 .@"extern" => {
...@@ -437,11 +424,11 @@ pub fn writeToMemory(val: Value, ty: Type, pt: Zcu.PerThread, buffer: []u8) erro...@@ -437,11 +424,11 @@ pub fn writeToMemory(val: Value, ty: Type, pt: Zcu.PerThread, buffer: []u8) erro
437 const field_type = Type.fromInterned(union_obj.field_types.get(ip)[field_index]);424 const field_type = Type.fromInterned(union_obj.field_types.get(ip)[field_index]);
438 const field_val = try val.fieldValue(pt, field_index);425 const field_val = try val.fieldValue(pt, field_index);
439 const byte_count: usize = @intCast(field_type.abiSize(zcu));426 const byte_count: usize = @intCast(field_type.abiSize(zcu));
440 return writeToMemory(field_val, field_type, pt, buffer[0..byte_count]);427 return writeToMemory(field_val, pt, buffer[0..byte_count]);
441 } else {428 } else {
442 const backing_ty = try ty.unionBackingType(pt);429 const backing_ty = try ty.unionBackingType(pt);
443 const byte_count: usize = @intCast(backing_ty.abiSize(zcu));430 const byte_count: usize = @intCast(backing_ty.abiSize(zcu));
444 return writeToMemory(val.unionValue(zcu), backing_ty, pt, buffer[0..byte_count]);431 return writeToMemory(val.unionValue(zcu), pt, buffer[0..byte_count]);
445 }432 }
446 },433 },
447 .@"packed" => {434 .@"packed" => {
...@@ -450,19 +437,13 @@ pub fn writeToMemory(val: Value, ty: Type, pt: Zcu.PerThread, buffer: []u8) erro...@@ -450,19 +437,13 @@ pub fn writeToMemory(val: Value, ty: Type, pt: Zcu.PerThread, buffer: []u8) erro
450 return writeToPackedMemory(val, ty, pt, buffer[0..byte_count], 0);437 return writeToPackedMemory(val, ty, pt, buffer[0..byte_count], 0);
451 },438 },
452 },439 },
453 .Pointer => {
454 if (ty.isSlice(zcu)) return error.IllDefinedMemoryLayout;
455 if (!val.ptrHasIntAddr(zcu)) return error.ReinterpretDeclRef;
456 return val.writeToMemory(Type.usize, pt, buffer);
457 },
458 .Optional => {440 .Optional => {
459 if (!ty.isPtrLikeOptional(zcu)) return error.IllDefinedMemoryLayout;441 if (!ty.isPtrLikeOptional(zcu)) return error.IllDefinedMemoryLayout;
460 const child = ty.optionalChild(zcu);
461 const opt_val = val.optionalValue(zcu);442 const opt_val = val.optionalValue(zcu);
462 if (opt_val) |some| {443 if (opt_val) |some| {
463 return some.writeToMemory(child, pt, buffer);444 return some.writeToMemory(pt, buffer);
464 } else {445 } else {
465 return writeToMemory(try pt.intValue(Type.usize, 0), Type.usize, pt, buffer);446 return writeToMemory(try pt.intValue(Type.usize, 0), pt, buffer);
466 }447 }
467 },448 },
468 else => return error.Unimplemented,449 else => return error.Unimplemented,
...@@ -582,7 +563,7 @@ pub fn writeToPackedMemory(...@@ -582,7 +563,7 @@ pub fn writeToPackedMemory(
582 },563 },
583 .Pointer => {564 .Pointer => {
584 assert(!ty.isSlice(zcu)); // No well defined layout.565 assert(!ty.isSlice(zcu)); // No well defined layout.
585 if (!val.ptrHasIntAddr(zcu)) return error.ReinterpretDeclRef;566 if (ip.getBackingAddrTag(val.toIntern()).? != .int) return error.ReinterpretDeclRef;
586 return val.writeToPackedMemory(Type.usize, pt, buffer, bit_offset);567 return val.writeToPackedMemory(Type.usize, pt, buffer, bit_offset);
587 },568 },
588 .Optional => {569 .Optional => {
...@@ -3658,14 +3639,15 @@ pub fn mulAddScalar(...@@ -3658,14 +3639,15 @@ pub fn mulAddScalar(
36583639
3659/// If the value is represented in-memory as a series of bytes that all3640/// If the value is represented in-memory as a series of bytes that all
3660/// have the same value, return that byte value, otherwise null.3641/// have the same value, return that byte value, otherwise null.
3661pub fn hasRepeatedByteRepr(val: Value, ty: Type, pt: Zcu.PerThread) !?u8 {3642pub fn hasRepeatedByteRepr(val: Value, pt: Zcu.PerThread) !?u8 {
3662 const zcu = pt.zcu;3643 const zcu = pt.zcu;
3644 const ty = val.typeOf(zcu);
3663 const abi_size = std.math.cast(usize, ty.abiSize(zcu)) orelse return null;3645 const abi_size = std.math.cast(usize, ty.abiSize(zcu)) orelse return null;
3664 assert(abi_size >= 1);3646 assert(abi_size >= 1);
3665 const byte_buffer = try zcu.gpa.alloc(u8, abi_size);3647 const byte_buffer = try zcu.gpa.alloc(u8, abi_size);
3666 defer zcu.gpa.free(byte_buffer);3648 defer zcu.gpa.free(byte_buffer);
36673649
3668 writeToMemory(val, ty, pt, byte_buffer) catch |err| switch (err) {3650 writeToMemory(val, pt, byte_buffer) catch |err| switch (err) {
3669 error.OutOfMemory => return error.OutOfMemory,3651 error.OutOfMemory => return error.OutOfMemory,
3670 error.ReinterpretDeclRef => return null,3652 error.ReinterpretDeclRef => return null,
3671 // TODO: The writeToMemory function was originally created for the purpose3653 // TODO: The writeToMemory function was originally created for the purpose
src/arch/wasm/CodeGen.zig+1-1
...@@ -3357,7 +3357,7 @@ fn lowerConstant(func: *CodeGen, val: Value, ty: Type) InnerError!WValue {...@@ -3357,7 +3357,7 @@ fn lowerConstant(func: *CodeGen, val: Value, ty: Type) InnerError!WValue {
3357 .vector_type => {3357 .vector_type => {
3358 assert(determineSimdStoreStrategy(ty, zcu, func.target.*) == .direct);3358 assert(determineSimdStoreStrategy(ty, zcu, func.target.*) == .direct);
3359 var buf: [16]u8 = undefined;3359 var buf: [16]u8 = undefined;
3360 val.writeToMemory(ty, pt, &buf) catch unreachable;3360 val.writeToMemory(pt, &buf) catch unreachable;
3361 return func.storeSimdImmd(buf);3361 return func.storeSimdImmd(buf);
3362 },3362 },
3363 .struct_type => {3363 .struct_type => {
src/codegen/llvm.zig+1-1
...@@ -9412,7 +9412,7 @@ pub const FuncGen = struct {...@@ -9412,7 +9412,7 @@ pub const FuncGen = struct {
9412 // repeating byte pattern, for example, `@as(u64, 0)` has a9412 // repeating byte pattern, for example, `@as(u64, 0)` has a
9413 // repeating byte pattern of 0 bytes. In such case, the memset9413 // repeating byte pattern of 0 bytes. In such case, the memset
9414 // intrinsic can be used.9414 // intrinsic can be used.
9415 if (try elem_val.hasRepeatedByteRepr(elem_ty, pt)) |byte_val| {9415 if (try elem_val.hasRepeatedByteRepr(pt)) |byte_val| {
9416 const fill_byte = try o.builder.intValue(.i8, byte_val);9416 const fill_byte = try o.builder.intValue(.i8, byte_val);
9417 const len = try self.sliceOrArrayLenInBytes(dest_slice, ptr_ty);9417 const len = try self.sliceOrArrayLenInBytes(dest_slice, ptr_ty);
9418 if (intrinsic_len0_traps) {9418 if (intrinsic_len0_traps) {
src/link.zig+2-1
...@@ -589,7 +589,8 @@ pub const File = struct {...@@ -589,7 +589,8 @@ pub const File = struct {
589 fs.File.WriteFileError ||589 fs.File.WriteFileError ||
590 fs.File.OpenError ||590 fs.File.OpenError ||
591 std.process.Child.SpawnError ||591 std.process.Child.SpawnError ||
592 fs.Dir.CopyFileError;592 fs.Dir.CopyFileError ||
593 FlushDebugInfoError;
593594
594 /// Commit pending changes and write headers. Takes into account final output mode595 /// Commit pending changes and write headers. Takes into account final output mode
595 /// and `use_lld`, not only `effectiveOutputMode`.596 /// and `use_lld`, not only `effectiveOutputMode`.
src/link/Dwarf.zig+88-18
...@@ -17,13 +17,21 @@ debug_loclists: DebugLocLists,...@@ -17,13 +17,21 @@ debug_loclists: DebugLocLists,
17debug_rnglists: DebugRngLists,17debug_rnglists: DebugRngLists,
18debug_str: StringSection,18debug_str: StringSection,
1919
20pub const UpdateError =20pub const UpdateError = error{
21 ReinterpretDeclRef,
22 IllDefinedMemoryLayout,
23 Unimplemented,
24 OutOfMemory,
25 EndOfStream,
26 Overflow,
27 Underflow,
28 UnexpectedEndOfFile,
29} ||
21 std.fs.File.OpenError ||30 std.fs.File.OpenError ||
22 std.fs.File.SetEndPosError ||31 std.fs.File.SetEndPosError ||
23 std.fs.File.CopyRangeError ||32 std.fs.File.CopyRangeError ||
24 std.fs.File.PReadError ||33 std.fs.File.PReadError ||
25 std.fs.File.PWriteError ||34 std.fs.File.PWriteError;
26 error{ EndOfStream, Overflow, Underflow, UnexpectedEndOfFile };
2735
28pub const FlushError =36pub const FlushError =
29 UpdateError ||37 UpdateError ||
...@@ -1401,7 +1409,7 @@ pub const WipNav = struct {...@@ -1401,7 +1409,7 @@ pub const WipNav = struct {
1401 else => Type.fromInterned(loaded_enum.tag_ty).intInfo(zcu).signedness,1409 else => Type.fromInterned(loaded_enum.tag_ty).intInfo(zcu).signedness,
1402 };1410 };
1403 if (loaded_enum.values.len > 0) {1411 if (loaded_enum.values.len > 0) {
1404 var big_int_space: InternPool.Key.Int.Storage.BigIntSpace = undefined;1412 var big_int_space: Value.BigIntSpace = undefined;
1405 const big_int = ip.indexToKey(loaded_enum.values.get(ip)[field_index]).int.storage.toBigInt(&big_int_space);1413 const big_int = ip.indexToKey(loaded_enum.values.get(ip)[field_index]).int.storage.toBigInt(&big_int_space);
1406 const bits = @max(1, big_int.bitCountTwosCompForSignedness(signedness));1414 const bits = @max(1, big_int.bitCountTwosCompForSignedness(signedness));
1407 if (bits <= 64) {1415 if (bits <= 64) {
...@@ -1429,9 +1437,12 @@ pub const WipNav = struct {...@@ -1429,9 +1437,12 @@ pub const WipNav = struct {
1429 }1437 }
1430 } else {1438 } else {
1431 try wip_nav.abbrevCode(abbrev_code.block);1439 try wip_nav.abbrevCode(abbrev_code.block);
1432 const bytes = Type.fromInterned(loaded_enum.tag_ty).abiSize(wip_nav.pt.zcu);1440 const bytes = Type.fromInterned(loaded_enum.tag_ty).abiSize(zcu);
1433 try uleb128(diw, bytes);1441 try uleb128(diw, bytes);
1434 big_int.writeTwosComplement(try wip_nav.debug_info.addManyAsSlice(wip_nav.dwarf.gpa, @intCast(bytes)), wip_nav.dwarf.endian);1442 big_int.writeTwosComplement(
1443 try wip_nav.debug_info.addManyAsSlice(wip_nav.dwarf.gpa, @intCast(bytes)),
1444 wip_nav.dwarf.endian,
1445 );
1435 }1446 }
1436 } else switch (signedness) {1447 } else switch (signedness) {
1437 .signed => {1448 .signed => {
...@@ -2566,8 +2577,17 @@ fn updateType(...@@ -2566,8 +2577,17 @@ fn updateType(
2566 .ptr_type => |ptr_type| switch (ptr_type.flags.size) {2577 .ptr_type => |ptr_type| switch (ptr_type.flags.size) {
2567 .One, .Many, .C => {2578 .One, .Many, .C => {
2568 const ptr_child_type = Type.fromInterned(ptr_type.child);2579 const ptr_child_type = Type.fromInterned(ptr_type.child);
2569 try wip_nav.abbrevCode(.ptr_type);2580 try wip_nav.abbrevCode(if (ptr_type.sentinel == .none) .ptr_type else .ptr_sentinel_type);
2570 try wip_nav.strp(name);2581 try wip_nav.strp(name);
2582 if (ptr_type.sentinel != .none) {
2583 const bytes = ptr_child_type.abiSize(zcu);
2584 try uleb128(diw, bytes);
2585 const mem = try wip_nav.debug_info.addManyAsSlice(dwarf.gpa, @intCast(bytes));
2586 Value.fromInterned(ptr_type.sentinel).writeToMemory(pt, mem) catch |err| switch (err) {
2587 error.IllDefinedMemoryLayout => @memset(mem, 0),
2588 else => |e| return e,
2589 };
2590 }
2571 try uleb128(diw, ptr_type.flags.alignment.toByteUnits() orelse2591 try uleb128(diw, ptr_type.flags.alignment.toByteUnits() orelse
2572 ptr_child_type.abiAlignment(zcu).toByteUnits().?);2592 ptr_child_type.abiAlignment(zcu).toByteUnits().?);
2573 try diw.writeByte(@intFromEnum(ptr_type.flags.address_space));2593 try diw.writeByte(@intFromEnum(ptr_type.flags.address_space));
...@@ -2609,16 +2629,34 @@ fn updateType(...@@ -2609,16 +2629,34 @@ fn updateType(
2609 try uleb128(diw, @intFromEnum(AbbrevCode.null));2629 try uleb128(diw, @intFromEnum(AbbrevCode.null));
2610 },2630 },
2611 },2631 },
2612 inline .array_type, .vector_type => |array_type, ty_tag| {2632 .array_type => |array_type| {
2613 try wip_nav.abbrevCode(.array_type);2633 const array_child_type = Type.fromInterned(array_type.child);
2634 try wip_nav.abbrevCode(if (array_type.sentinel == .none) .array_type else .array_sentinel_type);
2614 try wip_nav.strp(name);2635 try wip_nav.strp(name);
2615 try wip_nav.refType(Type.fromInterned(array_type.child));2636 if (array_type.sentinel != .none) {
2616 try diw.writeByte(@intFromBool(ty_tag == .vector_type));2637 const bytes = array_child_type.abiSize(zcu);
2638 try uleb128(diw, bytes);
2639 const mem = try wip_nav.debug_info.addManyAsSlice(dwarf.gpa, @intCast(bytes));
2640 Value.fromInterned(array_type.sentinel).writeToMemory(pt, mem) catch |err| switch (err) {
2641 error.IllDefinedMemoryLayout => @memset(mem, 0),
2642 else => |e| return e,
2643 };
2644 }
2645 try wip_nav.refType(array_child_type);
2617 try wip_nav.abbrevCode(.array_index);2646 try wip_nav.abbrevCode(.array_index);
2618 try wip_nav.refType(Type.usize);2647 try wip_nav.refType(Type.usize);
2619 try uleb128(diw, array_type.len);2648 try uleb128(diw, array_type.len);
2620 try uleb128(diw, @intFromEnum(AbbrevCode.null));2649 try uleb128(diw, @intFromEnum(AbbrevCode.null));
2621 },2650 },
2651 .vector_type => |vector_type| {
2652 try wip_nav.abbrevCode(.vector_type);
2653 try wip_nav.strp(name);
2654 try wip_nav.refType(Type.fromInterned(vector_type.child));
2655 try wip_nav.abbrevCode(.array_index);
2656 try wip_nav.refType(Type.usize);
2657 try uleb128(diw, vector_type.len);
2658 try uleb128(diw, @intFromEnum(AbbrevCode.null));
2659 },
2622 .opt_type => |opt_child_type_index| {2660 .opt_type => |opt_child_type_index| {
2623 const opt_child_type = Type.fromInterned(opt_child_type_index);2661 const opt_child_type = Type.fromInterned(opt_child_type_index);
2624 try wip_nav.abbrevCode(.union_type);2662 try wip_nav.abbrevCode(.union_type);
...@@ -2660,7 +2698,7 @@ fn updateType(...@@ -2660,7 +2698,7 @@ fn updateType(
2660 .error_set => {2698 .error_set => {
2661 try wip_nav.refType(Type.fromInterned(try pt.intern(.{ .int_type = .{2699 try wip_nav.refType(Type.fromInterned(try pt.intern(.{ .int_type = .{
2662 .signedness = .unsigned,2700 .signedness = .unsigned,
2663 .bits = pt.zcu.errorSetBits(),2701 .bits = zcu.errorSetBits(),
2664 } })));2702 } })));
2665 try uleb128(diw, 0);2703 try uleb128(diw, 0);
2666 },2704 },
...@@ -2729,7 +2767,7 @@ fn updateType(...@@ -2729,7 +2767,7 @@ fn updateType(
2729 try wip_nav.strp("is_error");2767 try wip_nav.strp("is_error");
2730 try wip_nav.refType(Type.fromInterned(try pt.intern(.{ .int_type = .{2768 try wip_nav.refType(Type.fromInterned(try pt.intern(.{ .int_type = .{
2731 .signedness = .unsigned,2769 .signedness = .unsigned,
2732 .bits = pt.zcu.errorSetBits(),2770 .bits = zcu.errorSetBits(),
2733 } })));2771 } })));
2734 try uleb128(diw, error_union_error_set_offset);2772 try uleb128(diw, error_union_error_set_offset);
27352773
...@@ -2892,7 +2930,7 @@ fn updateType(...@@ -2892,7 +2930,7 @@ fn updateType(
2892 try wip_nav.strp(name);2930 try wip_nav.strp(name);
2893 try wip_nav.refType(Type.fromInterned(try pt.intern(.{ .int_type = .{2931 try wip_nav.refType(Type.fromInterned(try pt.intern(.{ .int_type = .{
2894 .signedness = .unsigned,2932 .signedness = .unsigned,
2895 .bits = pt.zcu.errorSetBits(),2933 .bits = zcu.errorSetBits(),
2896 } })));2934 } })));
2897 for (0..error_set_type.names.len) |field_index| {2935 for (0..error_set_type.names.len) |field_index| {
2898 const field_name = error_set_type.names.get(ip)[field_index];2936 const field_name = error_set_type.names.get(ip)[field_index];
...@@ -3204,7 +3242,8 @@ fn refAbbrevCode(dwarf: *Dwarf, abbrev_code: AbbrevCode) UpdateError!@typeInfo(A...@@ -3204,7 +3242,8 @@ fn refAbbrevCode(dwarf: *Dwarf, abbrev_code: AbbrevCode) UpdateError!@typeInfo(A
3204}3242}
32053243
3206pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {3244pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {
3207 const ip = &pt.zcu.intern_pool;3245 const zcu = pt.zcu;
3246 const ip = &zcu.intern_pool;
3208 if (dwarf.types.get(.anyerror_type)) |entry| {3247 if (dwarf.types.get(.anyerror_type)) |entry| {
3209 var wip_nav: WipNav = .{3248 var wip_nav: WipNav = .{
3210 .dwarf = dwarf,3249 .dwarf = dwarf,
...@@ -3228,7 +3267,7 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {...@@ -3228,7 +3267,7 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {
3228 try wip_nav.strp("anyerror");3267 try wip_nav.strp("anyerror");
3229 try wip_nav.refType(Type.fromInterned(try pt.intern(.{ .int_type = .{3268 try wip_nav.refType(Type.fromInterned(try pt.intern(.{ .int_type = .{
3230 .signedness = .unsigned,3269 .signedness = .unsigned,
3231 .bits = pt.zcu.errorSetBits(),3270 .bits = zcu.errorSetBits(),
3232 } })));3271 } })));
3233 for (global_error_set_names, 1..) |name, value| {3272 for (global_error_set_names, 1..) |name, value| {
3234 try wip_nav.abbrevCode(.unsigned_enum_field);3273 try wip_nav.abbrevCode(.unsigned_enum_field);
...@@ -3455,7 +3494,7 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {...@@ -3455,7 +3494,7 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {
3455 uleb128(header.fixedWriter(), DW.FORM.line_strp) catch unreachable;3494 uleb128(header.fixedWriter(), DW.FORM.line_strp) catch unreachable;
3456 uleb128(header.fixedWriter(), mod_info.files.count()) catch unreachable;3495 uleb128(header.fixedWriter(), mod_info.files.count()) catch unreachable;
3457 for (mod_info.files.keys()) |file_index| {3496 for (mod_info.files.keys()) |file_index| {
3458 const file = pt.zcu.fileByIndex(file_index);3497 const file = zcu.fileByIndex(file_index);
3459 unit.cross_section_relocs.appendAssumeCapacity(.{3498 unit.cross_section_relocs.appendAssumeCapacity(.{
3460 .source_off = @intCast(header.items.len),3499 .source_off = @intCast(header.items.len),
3461 .target_sec = .debug_line_str,3500 .target_sec = .debug_line_str,
...@@ -3602,9 +3641,12 @@ const AbbrevCode = enum {...@@ -3602,9 +3641,12 @@ const AbbrevCode = enum {
3602 numeric_type,3641 numeric_type,
3603 inferred_error_set_type,3642 inferred_error_set_type,
3604 ptr_type,3643 ptr_type,
3644 ptr_sentinel_type,
3605 is_const,3645 is_const,
3606 is_volatile,3646 is_volatile,
3607 array_type,3647 array_type,
3648 array_sentinel_type,
3649 vector_type,
3608 array_index,3650 array_index,
3609 nullary_func_type,3651 nullary_func_type,
3610 func_type,3652 func_type,
...@@ -3913,6 +3955,16 @@ const AbbrevCode = enum {...@@ -3913,6 +3955,16 @@ const AbbrevCode = enum {
3913 .{ .type, .ref_addr },3955 .{ .type, .ref_addr },
3914 },3956 },
3915 },3957 },
3958 .ptr_sentinel_type = .{
3959 .tag = .pointer_type,
3960 .attrs = &.{
3961 .{ .name, .strp },
3962 .{ .ZIG_sentinel, .block },
3963 .{ .alignment, .udata },
3964 .{ .address_class, .data1 },
3965 .{ .type, .ref_addr },
3966 },
3967 },
3916 .is_const = .{3968 .is_const = .{
3917 .tag = .const_type,3969 .tag = .const_type,
3918 .attrs = &.{3970 .attrs = &.{
...@@ -3931,7 +3983,24 @@ const AbbrevCode = enum {...@@ -3931,7 +3983,24 @@ const AbbrevCode = enum {
3931 .attrs = &.{3983 .attrs = &.{
3932 .{ .name, .strp },3984 .{ .name, .strp },
3933 .{ .type, .ref_addr },3985 .{ .type, .ref_addr },
3934 .{ .GNU_vector, .flag },3986 },
3987 },
3988 .array_sentinel_type = .{
3989 .tag = .array_type,
3990 .children = true,
3991 .attrs = &.{
3992 .{ .name, .strp },
3993 .{ .ZIG_sentinel, .block },
3994 .{ .type, .ref_addr },
3995 },
3996 },
3997 .vector_type = .{
3998 .tag = .array_type,
3999 .children = true,
4000 .attrs = &.{
4001 .{ .name, .strp },
4002 .{ .type, .ref_addr },
4003 .{ .GNU_vector, .flag_present },
3935 },4004 },
3936 },4005 },
3937 .array_index = .{4006 .array_index = .{
...@@ -4132,6 +4201,7 @@ const Dwarf = @This();...@@ -4132,6 +4201,7 @@ const Dwarf = @This();
4132const InternPool = @import("../InternPool.zig");4201const InternPool = @import("../InternPool.zig");
4133const Module = @import("../Package.zig").Module;4202const Module = @import("../Package.zig").Module;
4134const Type = @import("../Type.zig");4203const Type = @import("../Type.zig");
4204const Value = @import("../Value.zig");
4135const Zcu = @import("../Zcu.zig");4205const Zcu = @import("../Zcu.zig");
4136const Zir = std.zig.Zir;4206const Zir = std.zig.Zir;
4137const assert = std.debug.assert;4207const assert = std.debug.assert;
test/src/Debugger.zig+76
...@@ -305,6 +305,82 @@ pub fn addTestsForTarget(db: *Debugger, target: Target) void {...@@ -305,6 +305,82 @@ pub fn addTestsForTarget(db: *Debugger, target: Target) void {
305 \\1 breakpoints deleted; 0 breakpoint locations disabled.305 \\1 breakpoints deleted; 0 breakpoint locations disabled.
306 },306 },
307 );307 );
308 db.addLldbTest(
309 "strings",
310 target,
311 &.{
312 .{
313 .path = "strings.zig",
314 .source =
315 \\const Strings = struct {
316 \\ c_ptr: [*c]const u8 = "c_ptr\x07\x08\t",
317 \\ many_ptr: [*:0]const u8 = "many_ptr\n\x0b\x0c",
318 \\ ptr_array: *const [12:0]u8 = "ptr_array\x00\r\x1b",
319 \\ slice: [:0]const u8 = "slice\"\'\\\x00",
320 \\};
321 \\fn testStrings(strings: Strings) void {
322 \\ _ = strings;
323 \\}
324 \\pub fn main() void {
325 \\ testStrings(.{});
326 \\}
327 \\
328 ,
329 },
330 },
331 \\breakpoint set --file strings.zig --source-pattern-regexp '_ = strings;'
332 \\process launch
333 \\frame variable --show-types strings.slice
334 \\frame variable --show-types --format character strings.slice
335 \\frame variable --show-types --format c-string strings
336 \\breakpoint delete --force 1
337 ,
338 &.{
339 \\(lldb) frame variable --show-types strings.slice
340 \\([:0]const u8) strings.slice = len=9 {
341 \\ (u8) [0] = 115
342 \\ (u8) [1] = 108
343 \\ (u8) [2] = 105
344 \\ (u8) [3] = 99
345 \\ (u8) [4] = 101
346 \\ (u8) [5] = 34
347 \\ (u8) [6] = 39
348 \\ (u8) [7] = 92
349 \\ (u8) [8] = 0
350 \\}
351 \\(lldb) frame variable --show-types --format character strings.slice
352 \\([:0]const u8) strings.slice = len=9 {
353 \\ (u8) [0] = 's'
354 \\ (u8) [1] = 'l'
355 \\ (u8) [2] = 'i'
356 \\ (u8) [3] = 'c'
357 \\ (u8) [4] = 'e'
358 \\ (u8) [5] = '\"'
359 \\ (u8) [6] = '\''
360 \\ (u8) [7] = '\\'
361 \\ (u8) [8] = '\x00'
362 \\}
363 \\(lldb) frame variable --show-types --format c-string strings
364 \\(root.strings.Strings) strings = {
365 \\ ([*c]const u8) c_ptr = "c_ptr\x07\x08\t"
366 \\ ([*:0]const u8) many_ptr = "many_ptr\n\x0b\x0c"
367 \\ (*const [12:0]u8) ptr_array = "ptr_array\x00\r\x1b"
368 \\ ([:0]const u8) slice = "slice\"\'\\\x00" len=9 {
369 \\ (u8) [0] = "s"
370 \\ (u8) [1] = "l"
371 \\ (u8) [2] = "i"
372 \\ (u8) [3] = "c"
373 \\ (u8) [4] = "e"
374 \\ (u8) [5] = "\""
375 \\ (u8) [6] = "\'"
376 \\ (u8) [7] = "\\"
377 \\ (u8) [8] = "\x00"
378 \\ }
379 \\}
380 \\(lldb) breakpoint delete --force 1
381 \\1 breakpoints deleted; 0 breakpoint locations disabled.
382 },
383 );
308 db.addLldbTest(384 db.addLldbTest(
309 "enums",385 "enums",
310 target,386 target,