Merge pull request #22252 from jacobly0/dwarf-deduped-structs

Dwarf: preserve deduped struct navs
This commit is contained in:
Andrew Kelley 2024-12-17 01:26:09 -05:00 committed by GitHub
commit debba652a3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 1045 additions and 210 deletions

View file

@ -224,6 +224,8 @@ pub const ZIG_parent = 0x2ccd;
pub const ZIG_padding = 0x2cce;
pub const ZIG_relative_decl = 0x2cd0;
pub const ZIG_decl_line_relative = 0x2cd1;
pub const ZIG_comptime_value = 0x2cd2;
pub const ZIG_comptime_default_value = 0x2cd3;
pub const ZIG_sentinel = 0x2ce2;
// UPC extension.

View file

@ -119,3 +119,4 @@ pub const PGI_interface_block = 0xA020;
// ZIG extensions.
pub const ZIG_padding = 0xfdb1;
pub const ZIG_comptime_value = 0xfdb2;

View file

@ -1163,7 +1163,7 @@ const Local = struct {
capacity: u32,
};
fn header(list: ListSelf) *Header {
return @ptrFromInt(@intFromPtr(list.bytes) - bytes_offset);
return @alignCast(@ptrCast(list.bytes - bytes_offset));
}
pub fn view(list: ListSelf) View {
const capacity = list.header().capacity;
@ -1372,7 +1372,7 @@ const Shard = struct {
}
};
fn header(map: @This()) *Header {
return @ptrFromInt(@intFromPtr(map.entries) - entries_offset);
return @alignCast(@ptrCast(@as([*]u8, @ptrCast(map.entries)) - entries_offset));
}
const Entry = extern struct {
@ -4704,9 +4704,45 @@ pub const Index = enum(u32) {
}
comptime {
if (builtin.zig_backend == .stage2_llvm and !builtin.strip_debug_info) {
_ = &dbHelper;
}
if (!builtin.strip_debug_info) switch (builtin.zig_backend) {
.stage2_llvm => _ = &dbHelper,
.stage2_x86_64 => {
for (@typeInfo(Tag).@"enum".fields) |tag| {
if (!@hasField(@TypeOf(Tag.encodings), tag.name)) {
if (false) @compileLog("missing: " ++ @typeName(Tag) ++ ".encodings." ++ tag.name);
continue;
}
const encoding = @field(Tag.encodings, tag.name);
for (@typeInfo(encoding.trailing).@"struct".fields) |field| {
struct {
fn checkConfig(name: []const u8) void {
if (!@hasField(@TypeOf(encoding.config), name)) @compileError("missing field: " ++ @typeName(Tag) ++ ".encodings." ++ tag.name ++ ".config.@\"" ++ name ++ "\"");
const FieldType = @TypeOf(@field(encoding.config, name));
if (@typeInfo(FieldType) != .enum_literal) @compileError("expected enum literal: " ++ @typeName(Tag) ++ ".encodings." ++ tag.name ++ ".config.@\"" ++ name ++ "\": " ++ @typeName(FieldType));
}
fn checkField(name: []const u8, Type: type) void {
switch (@typeInfo(Type)) {
.int => {},
.@"enum" => {},
.@"struct" => |info| assert(info.layout == .@"packed"),
.optional => |info| {
checkConfig(name ++ ".?");
checkField(name ++ ".?", info.child);
},
.pointer => |info| {
assert(info.size == .Slice);
checkConfig(name ++ ".len");
checkField(name ++ "[0]", info.child);
},
else => @compileError("unsupported type: " ++ @typeName(Tag) ++ ".encodings." ++ tag.name ++ "." ++ name ++ ": " ++ @typeName(Type)),
}
}
}.checkField("trailing." ++ field.name, field.type);
}
}
},
else => {},
};
}
};
@ -5302,6 +5338,39 @@ pub const Tag = enum(u8) {
};
}
const encodings = .{
.type_struct = .{
.payload = TypeStruct,
.trailing = struct {
captures_len: ?u32,
captures: ?[]CaptureValue,
type_hash: ?u64,
field_types: []Index,
field_inits: ?[]Index,
field_aligns: ?[]Alignment,
field_is_comptime_bits: ?[]u32,
field_index: ?[]LoadedStructType.RuntimeOrder,
field_offset: []u32,
},
.config = .{
.@"trailing.captures_len.?" = .@"payload.flags.any_captures",
.@"trailing.captures.?" = .@"payload.flags.any_captures",
.@"trailing.captures.?.len" = .@"trailing.captures_len",
.@"trailing.type_hash.?" = .@"payload.flags.is_reified",
.@"trailing.field_types.len" = .@"payload.fields_len",
.@"trailing.field_inits.?" = .@"payload.flags.any_default_inits",
.@"trailing.field_inits.?.len" = .@"payload.fields_len",
.@"trailing.field_aligns.?" = .@"payload.flags.any_aligned_fields",
.@"trailing.field_aligns.?.len" = .@"payload.fields_len",
.@"trailing.field_is_comptime_bits.?" = .@"payload.flags.any_comptime_fields",
.@"trailing.field_is_comptime_bits.?.len" = .@"(payload.fields_len + 31) / 32",
.@"trailing.field_index.?" = .@"!payload.flags.is_extern",
.@"trailing.field_index.?.len" = .@"!payload.flags.is_extern",
.@"trailing.field_offset.len" = .@"payload.fields_len",
},
},
};
pub const Variable = struct {
ty: Index,
/// May be `none`.

View file

@ -4126,6 +4126,7 @@ pub const @"anyframe": Type = .{ .ip_index = .anyframe_type };
pub const @"null": Type = .{ .ip_index = .null_type };
pub const @"undefined": Type = .{ .ip_index = .undefined_type };
pub const @"noreturn": Type = .{ .ip_index = .noreturn_type };
pub const enum_literal: Type = .{ .ip_index = .enum_literal_type };
pub const @"c_char": Type = .{ .ip_index = .c_char_type };
pub const @"c_short": Type = .{ .ip_index = .c_short_type };

File diff suppressed because it is too large Load diff

View file

@ -7,10 +7,28 @@
import lldb
import re
# Helpers
page_size = 1 << 12
def log2_int(i): return i.bit_length() - 1
def create_struct(name, struct_type, **inits):
struct_bytes = bytearray(struct_type.size)
struct_data = lldb.SBData()
for field in struct_type.fields:
field_size = field.type.size
field_bytes = inits[field.name].data.uint8[:field_size]
match struct_data.byte_order:
case lldb.eByteOrderLittle:
field_start = field.byte_offset
struct_bytes[field_start:field_start + len(field_bytes)] = field_bytes
case lldb.eByteOrderBig:
field_end = field.byte_offset + field_size
struct_bytes[field_end - len(field_bytes):field_end] = field_bytes
struct_data.SetData(lldb.SBError(), struct_bytes, struct_data.byte_order, struct_data.GetAddressByteSize())
return next(iter(inits.values())).CreateValueFromData(name, struct_data, struct_type)
# Define Zig Language
zig_keywords = {
@ -678,6 +696,22 @@ value_tag_handlers = {
'lazy_size': lambda payload: '@sizeOf(%s)' % type_Type_SummaryProvider(payload),
}
# Define Zig Stage2 Compiler (compiled with the self-hosted backend)
class root_InternPool_Local_List_SynthProvider:
def __init__(self, value, _=None): self.value = value
def update(self):
capacity = self.value.EvaluateExpression('@as(*@This().Header, @alignCast(@ptrCast(@this().bytes - @This().bytes_offset))).capacity')
self.view = create_struct('view', self.value.EvaluateExpression('@This().View').GetValueAsType(), bytes=self.value.GetChildMemberWithName('bytes'), len=capacity, capacity=capacity).GetNonSyntheticValue()
def has_children(self): return True
def num_children(self): return 1
def get_child_index(self, name):
try: return ('view',).index(name)
except: pass
def get_child_at_index(self, index):
try: return (self.view,)[index]
except: pass
# Initialize
def add(debugger, *, category, regex=False, type, identifier=None, synth=False, inline_children=False, expand=False, summary=False):
@ -729,3 +763,6 @@ def __lldb_init_module(debugger, _=None):
add(debugger, category='zig.stage2', type='InternPool.Key.Ptr.Addr', identifier='zig_TaggedUnion', synth=True)
add(debugger, category='zig.stage2', type='InternPool.Key.Aggregate.Storage', identifier='zig_TaggedUnion', synth=True)
add(debugger, category='zig.stage2', type='arch.x86_64.CodeGen.MCValue', identifier='zig_TaggedUnion', synth=True, inline_children=True, summary=True)
# Initialize Zig Stage2 Compiler (compiled with the self-hosted backend)
add(debugger, category='zig', regex=True, type='^root\\.InternPool\\.Local\\.List\\(.*\\)$', identifier='root_InternPool_Local_List', synth=True, expand=True, summary='capacity=${var%#}')