| ... | @@ -19,6 +19,8 @@ di_atom_last_index: ?Atom.Index = null, | ... | @@ -19,6 +19,8 @@ di_atom_last_index: ?Atom.Index = null, |
| 19 | di_atoms: std.ArrayListUnmanaged(Atom) = .{}, | 19 | di_atoms: std.ArrayListUnmanaged(Atom) = .{}, |
| 20 | di_atom_decls: AtomTable = .{}, | 20 | di_atom_decls: AtomTable = .{}, |
| 21 | | 21 | |
| | 22 | dbg_line_header: DbgLineHeader, |
| | 23 | |
| 22 | abbrev_table_offset: ?u64 = null, | 24 | abbrev_table_offset: ?u64 = null, |
| 23 | | 25 | |
| 24 | /// TODO replace with InternPool | 26 | /// TODO replace with InternPool |
| ... | @@ -50,48 +52,48 @@ const Atom = struct { | ... | @@ -50,48 +52,48 @@ const Atom = struct { |
| 50 | pub const Index = u32; | 52 | pub const Index = u32; |
| 51 | }; | 53 | }; |
| 52 | | 54 | |
| | 55 | const DbgLineHeader = struct { |
| | 56 | minimum_instruction_length: u8, |
| | 57 | maximum_operations_per_instruction: u8, |
| | 58 | default_is_stmt: bool, |
| | 59 | line_base: i8, |
| | 60 | line_range: u8, |
| | 61 | opcode_base: u8, |
| | 62 | }; |
| | 63 | |
| 53 | /// Represents state of the analysed Decl. | 64 | /// Represents state of the analysed Decl. |
| 54 | /// Includes Decl's abbrev table of type Types, matching arena | 65 | /// Includes Decl's abbrev table of type Types, matching arena |
| 55 | /// and a set of relocations that will be resolved once this | 66 | /// and a set of relocations that will be resolved once this |
| 56 | /// Decl's inner Atom is assigned an offset within the DWARF section. | 67 | /// Decl's inner Atom is assigned an offset within the DWARF section. |
| 57 | pub const DeclState = struct { | 68 | pub const DeclState = struct { |
| 58 | gpa: Allocator, | 69 | dwarf: *Dwarf, |
| 59 | mod: *Module, | 70 | mod: *Module, |
| 60 | di_atom_decls: *const AtomTable, | 71 | di_atom_decls: *const AtomTable, |
| | 72 | dbg_line_func: InternPool.Index, |
| 61 | dbg_line: std.ArrayList(u8), | 73 | dbg_line: std.ArrayList(u8), |
| 62 | dbg_info: std.ArrayList(u8), | 74 | dbg_info: std.ArrayList(u8), |
| 63 | abbrev_type_arena: std.heap.ArenaAllocator, | 75 | abbrev_type_arena: std.heap.ArenaAllocator, |
| 64 | abbrev_table: std.ArrayListUnmanaged(AbbrevEntry) = .{}, | 76 | abbrev_table: std.ArrayListUnmanaged(AbbrevEntry), |
| 65 | abbrev_resolver: std.AutoHashMapUnmanaged(InternPool.Index, u32) = .{}, | 77 | abbrev_resolver: std.AutoHashMapUnmanaged(InternPool.Index, u32), |
| 66 | abbrev_relocs: std.ArrayListUnmanaged(AbbrevRelocation) = .{}, | 78 | abbrev_relocs: std.ArrayListUnmanaged(AbbrevRelocation), |
| 67 | exprloc_relocs: std.ArrayListUnmanaged(ExprlocRelocation) = .{}, | 79 | exprloc_relocs: std.ArrayListUnmanaged(ExprlocRelocation), |
| 68 | | | |
| 69 | fn init(gpa: Allocator, mod: *Module, di_atom_decls: *const AtomTable) DeclState { | | |
| 70 | return .{ | | |
| 71 | .gpa = gpa, | | |
| 72 | .mod = mod, | | |
| 73 | .di_atom_decls = di_atom_decls, | | |
| 74 | .dbg_line = std.ArrayList(u8).init(gpa), | | |
| 75 | .dbg_info = std.ArrayList(u8).init(gpa), | | |
| 76 | .abbrev_type_arena = std.heap.ArenaAllocator.init(gpa), | | |
| 77 | }; | | |
| 78 | } | | |
| 79 | | 80 | |
| 80 | pub fn deinit(self: *DeclState) void { | 81 | pub fn deinit(self: *DeclState) void { |
| | 82 | const gpa = self.dwarf.allocator; |
| 81 | self.dbg_line.deinit(); | 83 | self.dbg_line.deinit(); |
| 82 | self.dbg_info.deinit(); | 84 | self.dbg_info.deinit(); |
| 83 | self.abbrev_type_arena.deinit(); | 85 | self.abbrev_type_arena.deinit(); |
| 84 | self.abbrev_table.deinit(self.gpa); | 86 | self.abbrev_table.deinit(gpa); |
| 85 | self.abbrev_resolver.deinit(self.gpa); | 87 | self.abbrev_resolver.deinit(gpa); |
| 86 | self.abbrev_relocs.deinit(self.gpa); | 88 | self.abbrev_relocs.deinit(gpa); |
| 87 | self.exprloc_relocs.deinit(self.gpa); | 89 | self.exprloc_relocs.deinit(gpa); |
| 88 | } | 90 | } |
| 89 | | 91 | |
| 90 | /// Adds local type relocation of the form: @offset => @this + addend | 92 | /// Adds local type relocation of the form: @offset => @this + addend |
| 91 | /// @this signifies the offset within the .debug_abbrev section of the containing atom. | 93 | /// @this signifies the offset within the .debug_abbrev section of the containing atom. |
| 92 | fn addTypeRelocLocal(self: *DeclState, atom_index: Atom.Index, offset: u32, addend: u32) !void { | 94 | fn addTypeRelocLocal(self: *DeclState, atom_index: Atom.Index, offset: u32, addend: u32) !void { |
| 93 | log.debug("{x}: @this + {x}", .{ offset, addend }); | 95 | log.debug("{x}: @this + {x}", .{ offset, addend }); |
| 94 | try self.abbrev_relocs.append(self.gpa, .{ | 96 | try self.abbrev_relocs.append(self.dwarf.allocator, .{ |
| 95 | .target = null, | 97 | .target = null, |
| 96 | .atom_index = atom_index, | 98 | .atom_index = atom_index, |
| 97 | .offset = offset, | 99 | .offset = offset, |
| ... | @@ -103,19 +105,20 @@ pub const DeclState = struct { | ... | @@ -103,19 +105,20 @@ pub const DeclState = struct { |
| 103 | /// @symbol signifies a type abbreviation posititioned somewhere in the .debug_abbrev section | 105 | /// @symbol signifies a type abbreviation posititioned somewhere in the .debug_abbrev section |
| 104 | /// which we use as our target of the relocation. | 106 | /// which we use as our target of the relocation. |
| 105 | fn addTypeRelocGlobal(self: *DeclState, atom_index: Atom.Index, ty: Type, offset: u32) !void { | 107 | fn addTypeRelocGlobal(self: *DeclState, atom_index: Atom.Index, ty: Type, offset: u32) !void { |
| | 108 | const gpa = self.dwarf.allocator; |
| 106 | const resolv = self.abbrev_resolver.get(ty.toIntern()) orelse blk: { | 109 | const resolv = self.abbrev_resolver.get(ty.toIntern()) orelse blk: { |
| 107 | const sym_index = @as(u32, @intCast(self.abbrev_table.items.len)); | 110 | const sym_index: u32 = @intCast(self.abbrev_table.items.len); |
| 108 | try self.abbrev_table.append(self.gpa, .{ | 111 | try self.abbrev_table.append(gpa, .{ |
| 109 | .atom_index = atom_index, | 112 | .atom_index = atom_index, |
| 110 | .type = ty, | 113 | .type = ty, |
| 111 | .offset = undefined, | 114 | .offset = undefined, |
| 112 | }); | 115 | }); |
| 113 | log.debug("%{d}: {}", .{ sym_index, ty.fmt(self.mod) }); | 116 | log.debug("%{d}: {}", .{ sym_index, ty.fmt(self.mod) }); |
| 114 | try self.abbrev_resolver.putNoClobber(self.gpa, ty.toIntern(), sym_index); | 117 | try self.abbrev_resolver.putNoClobber(gpa, ty.toIntern(), sym_index); |
| 115 | break :blk sym_index; | 118 | break :blk sym_index; |
| 116 | }; | 119 | }; |
| 117 | log.debug("{x}: %{d} + 0", .{ offset, resolv }); | 120 | log.debug("{x}: %{d} + 0", .{ offset, resolv }); |
| 118 | try self.abbrev_relocs.append(self.gpa, .{ | 121 | try self.abbrev_relocs.append(gpa, .{ |
| 119 | .target = resolv, | 122 | .target = resolv, |
| 120 | .atom_index = atom_index, | 123 | .atom_index = atom_index, |
| 121 | .offset = offset, | 124 | .offset = offset, |
| ... | @@ -192,7 +195,7 @@ pub const DeclState = struct { | ... | @@ -192,7 +195,7 @@ pub const DeclState = struct { |
| 192 | // DW.AT.type, DW.FORM.ref4 | 195 | // DW.AT.type, DW.FORM.ref4 |
| 193 | var index = dbg_info_buffer.items.len; | 196 | var index = dbg_info_buffer.items.len; |
| 194 | try dbg_info_buffer.resize(index + 4); | 197 | try dbg_info_buffer.resize(index + 4); |
| 195 | try self.addTypeRelocGlobal(atom_index, Type.bool, @as(u32, @intCast(index))); | 198 | try self.addTypeRelocGlobal(atom_index, Type.bool, @intCast(index)); |
| 196 | // DW.AT.data_member_location, DW.FORM.udata | 199 | // DW.AT.data_member_location, DW.FORM.udata |
| 197 | try dbg_info_buffer.ensureUnusedCapacity(6); | 200 | try dbg_info_buffer.ensureUnusedCapacity(6); |
| 198 | dbg_info_buffer.appendAssumeCapacity(0); | 201 | dbg_info_buffer.appendAssumeCapacity(0); |
| ... | @@ -204,7 +207,7 @@ pub const DeclState = struct { | ... | @@ -204,7 +207,7 @@ pub const DeclState = struct { |
| 204 | // DW.AT.type, DW.FORM.ref4 | 207 | // DW.AT.type, DW.FORM.ref4 |
| 205 | index = dbg_info_buffer.items.len; | 208 | index = dbg_info_buffer.items.len; |
| 206 | try dbg_info_buffer.resize(index + 4); | 209 | try dbg_info_buffer.resize(index + 4); |
| 207 | try self.addTypeRelocGlobal(atom_index, payload_ty, @as(u32, @intCast(index))); | 210 | try self.addTypeRelocGlobal(atom_index, payload_ty, @intCast(index)); |
| 208 | // DW.AT.data_member_location, DW.FORM.udata | 211 | // DW.AT.data_member_location, DW.FORM.udata |
| 209 | const offset = abi_size - payload_ty.abiSize(mod); | 212 | const offset = abi_size - payload_ty.abiSize(mod); |
| 210 | try leb128.writeULEB128(dbg_info_buffer.writer(), offset); | 213 | try leb128.writeULEB128(dbg_info_buffer.writer(), offset); |
| ... | @@ -216,7 +219,7 @@ pub const DeclState = struct { | ... | @@ -216,7 +219,7 @@ pub const DeclState = struct { |
| 216 | if (ty.isSlice(mod)) { | 219 | if (ty.isSlice(mod)) { |
| 217 | // Slices are structs: struct { .ptr = *, .len = N } | 220 | // Slices are structs: struct { .ptr = *, .len = N } |
| 218 | const ptr_bits = target.ptrBitWidth(); | 221 | const ptr_bits = target.ptrBitWidth(); |
| 219 | const ptr_bytes = @as(u8, @intCast(@divExact(ptr_bits, 8))); | 222 | const ptr_bytes: u8 = @intCast(@divExact(ptr_bits, 8)); |
| 220 | // DW.AT.structure_type | 223 | // DW.AT.structure_type |
| 221 | try dbg_info_buffer.ensureUnusedCapacity(2); | 224 | try dbg_info_buffer.ensureUnusedCapacity(2); |
| 222 | dbg_info_buffer.appendAssumeCapacity(@intFromEnum(AbbrevKind.struct_type)); | 225 | dbg_info_buffer.appendAssumeCapacity(@intFromEnum(AbbrevKind.struct_type)); |
| ... | @@ -234,7 +237,7 @@ pub const DeclState = struct { | ... | @@ -234,7 +237,7 @@ pub const DeclState = struct { |
| 234 | var index = dbg_info_buffer.items.len; | 237 | var index = dbg_info_buffer.items.len; |
| 235 | try dbg_info_buffer.resize(index + 4); | 238 | try dbg_info_buffer.resize(index + 4); |
| 236 | const ptr_ty = ty.slicePtrFieldType(mod); | 239 | const ptr_ty = ty.slicePtrFieldType(mod); |
| 237 | try self.addTypeRelocGlobal(atom_index, ptr_ty, @as(u32, @intCast(index))); | 240 | try self.addTypeRelocGlobal(atom_index, ptr_ty, @intCast(index)); |
| 238 | // DW.AT.data_member_location, DW.FORM.udata | 241 | // DW.AT.data_member_location, DW.FORM.udata |
| 239 | try dbg_info_buffer.ensureUnusedCapacity(6); | 242 | try dbg_info_buffer.ensureUnusedCapacity(6); |
| 240 | dbg_info_buffer.appendAssumeCapacity(0); | 243 | dbg_info_buffer.appendAssumeCapacity(0); |
| ... | @@ -246,7 +249,7 @@ pub const DeclState = struct { | ... | @@ -246,7 +249,7 @@ pub const DeclState = struct { |
| 246 | // DW.AT.type, DW.FORM.ref4 | 249 | // DW.AT.type, DW.FORM.ref4 |
| 247 | index = dbg_info_buffer.items.len; | 250 | index = dbg_info_buffer.items.len; |
| 248 | try dbg_info_buffer.resize(index + 4); | 251 | try dbg_info_buffer.resize(index + 4); |
| 249 | try self.addTypeRelocGlobal(atom_index, Type.usize, @as(u32, @intCast(index))); | 252 | try self.addTypeRelocGlobal(atom_index, Type.usize, @intCast(index)); |
| 250 | // DW.AT.data_member_location, DW.FORM.udata | 253 | // DW.AT.data_member_location, DW.FORM.udata |
| 251 | try dbg_info_buffer.ensureUnusedCapacity(2); | 254 | try dbg_info_buffer.ensureUnusedCapacity(2); |
| 252 | dbg_info_buffer.appendAssumeCapacity(ptr_bytes); | 255 | dbg_info_buffer.appendAssumeCapacity(ptr_bytes); |
| ... | @@ -258,7 +261,7 @@ pub const DeclState = struct { | ... | @@ -258,7 +261,7 @@ pub const DeclState = struct { |
| 258 | // DW.AT.type, DW.FORM.ref4 | 261 | // DW.AT.type, DW.FORM.ref4 |
| 259 | const index = dbg_info_buffer.items.len; | 262 | const index = dbg_info_buffer.items.len; |
| 260 | try dbg_info_buffer.resize(index + 4); | 263 | try dbg_info_buffer.resize(index + 4); |
| 261 | try self.addTypeRelocGlobal(atom_index, ty.childType(mod), @as(u32, @intCast(index))); | 264 | try self.addTypeRelocGlobal(atom_index, ty.childType(mod), @intCast(index)); |
| 262 | } | 265 | } |
| 263 | }, | 266 | }, |
| 264 | .Array => { | 267 | .Array => { |
| ... | @@ -269,13 +272,13 @@ pub const DeclState = struct { | ... | @@ -269,13 +272,13 @@ pub const DeclState = struct { |
| 269 | // DW.AT.type, DW.FORM.ref4 | 272 | // DW.AT.type, DW.FORM.ref4 |
| 270 | var index = dbg_info_buffer.items.len; | 273 | var index = dbg_info_buffer.items.len; |
| 271 | try dbg_info_buffer.resize(index + 4); | 274 | try dbg_info_buffer.resize(index + 4); |
| 272 | try self.addTypeRelocGlobal(atom_index, ty.childType(mod), @as(u32, @intCast(index))); | 275 | try self.addTypeRelocGlobal(atom_index, ty.childType(mod), @intCast(index)); |
| 273 | // DW.AT.subrange_type | 276 | // DW.AT.subrange_type |
| 274 | try dbg_info_buffer.append(@intFromEnum(AbbrevKind.array_dim)); | 277 | try dbg_info_buffer.append(@intFromEnum(AbbrevKind.array_dim)); |
| 275 | // DW.AT.type, DW.FORM.ref4 | 278 | // DW.AT.type, DW.FORM.ref4 |
| 276 | index = dbg_info_buffer.items.len; | 279 | index = dbg_info_buffer.items.len; |
| 277 | try dbg_info_buffer.resize(index + 4); | 280 | try dbg_info_buffer.resize(index + 4); |
| 278 | try self.addTypeRelocGlobal(atom_index, Type.usize, @as(u32, @intCast(index))); | 281 | try self.addTypeRelocGlobal(atom_index, Type.usize, @intCast(index)); |
| 279 | // DW.AT.count, DW.FORM.udata | 282 | // DW.AT.count, DW.FORM.udata |
| 280 | const len = ty.arrayLenIncludingSentinel(mod); | 283 | const len = ty.arrayLenIncludingSentinel(mod); |
| 281 | try leb128.writeULEB128(dbg_info_buffer.writer(), len); | 284 | try leb128.writeULEB128(dbg_info_buffer.writer(), len); |
| ... | @@ -302,7 +305,7 @@ pub const DeclState = struct { | ... | @@ -302,7 +305,7 @@ pub const DeclState = struct { |
| 302 | // DW.AT.type, DW.FORM.ref4 | 305 | // DW.AT.type, DW.FORM.ref4 |
| 303 | var index = dbg_info_buffer.items.len; | 306 | var index = dbg_info_buffer.items.len; |
| 304 | try dbg_info_buffer.resize(index + 4); | 307 | try dbg_info_buffer.resize(index + 4); |
| 305 | try self.addTypeRelocGlobal(atom_index, field_ty.toType(), @as(u32, @intCast(index))); | 308 | try self.addTypeRelocGlobal(atom_index, field_ty.toType(), @intCast(index)); |
| 306 | // DW.AT.data_member_location, DW.FORM.udata | 309 | // DW.AT.data_member_location, DW.FORM.udata |
| 307 | const field_off = ty.structFieldOffset(field_index, mod); | 310 | const field_off = ty.structFieldOffset(field_index, mod); |
| 308 | try leb128.writeULEB128(dbg_info_buffer.writer(), field_off); | 311 | try leb128.writeULEB128(dbg_info_buffer.writer(), field_off); |
| ... | @@ -328,7 +331,7 @@ pub const DeclState = struct { | ... | @@ -328,7 +331,7 @@ pub const DeclState = struct { |
| 328 | // DW.AT.type, DW.FORM.ref4 | 331 | // DW.AT.type, DW.FORM.ref4 |
| 329 | var index = dbg_info_buffer.items.len; | 332 | var index = dbg_info_buffer.items.len; |
| 330 | try dbg_info_buffer.resize(index + 4); | 333 | try dbg_info_buffer.resize(index + 4); |
| 331 | try self.addTypeRelocGlobal(atom_index, field_ty.toType(), @as(u32, @intCast(index))); | 334 | try self.addTypeRelocGlobal(atom_index, field_ty.toType(), @intCast(index)); |
| 332 | // DW.AT.data_member_location, DW.FORM.udata | 335 | // DW.AT.data_member_location, DW.FORM.udata |
| 333 | try leb128.writeULEB128(dbg_info_buffer.writer(), field_off); | 336 | try leb128.writeULEB128(dbg_info_buffer.writer(), field_off); |
| 334 | } | 337 | } |
| ... | @@ -387,7 +390,7 @@ pub const DeclState = struct { | ... | @@ -387,7 +390,7 @@ pub const DeclState = struct { |
| 387 | // TODO do not assume a 64bit enum value - could be bigger. | 390 | // TODO do not assume a 64bit enum value - could be bigger. |
| 388 | // See https://github.com/ziglang/zig/issues/645 | 391 | // See https://github.com/ziglang/zig/issues/645 |
| 389 | const field_int_val = try value.toValue().intFromEnum(ty, mod); | 392 | const field_int_val = try value.toValue().intFromEnum(ty, mod); |
| 390 | break :value @as(u64, @bitCast(field_int_val.toSignedInt(mod))); | 393 | break :value @bitCast(field_int_val.toSignedInt(mod)); |
| 391 | }; | 394 | }; |
| 392 | mem.writeInt(u64, dbg_info_buffer.addManyAsArrayAssumeCapacity(8), value, target_endian); | 395 | mem.writeInt(u64, dbg_info_buffer.addManyAsArrayAssumeCapacity(8), value, target_endian); |
| 393 | } | 396 | } |
| ... | @@ -422,7 +425,7 @@ pub const DeclState = struct { | ... | @@ -422,7 +425,7 @@ pub const DeclState = struct { |
| 422 | // DW.AT.type, DW.FORM.ref4 | 425 | // DW.AT.type, DW.FORM.ref4 |
| 423 | const inner_union_index = dbg_info_buffer.items.len; | 426 | const inner_union_index = dbg_info_buffer.items.len; |
| 424 | try dbg_info_buffer.resize(inner_union_index + 4); | 427 | try dbg_info_buffer.resize(inner_union_index + 4); |
| 425 | try self.addTypeRelocLocal(atom_index, @as(u32, @intCast(inner_union_index)), 5); | 428 | try self.addTypeRelocLocal(atom_index, @intCast(inner_union_index), 5); |
| 426 | // DW.AT.data_member_location, DW.FORM.udata | 429 | // DW.AT.data_member_location, DW.FORM.udata |
| 427 | try leb128.writeULEB128(dbg_info_buffer.writer(), payload_offset); | 430 | try leb128.writeULEB128(dbg_info_buffer.writer(), payload_offset); |
| 428 | } | 431 | } |
| ... | @@ -502,7 +505,7 @@ pub const DeclState = struct { | ... | @@ -502,7 +505,7 @@ pub const DeclState = struct { |
| 502 | // DW.AT.type, DW.FORM.ref4 | 505 | // DW.AT.type, DW.FORM.ref4 |
| 503 | const index = dbg_info_buffer.items.len; | 506 | const index = dbg_info_buffer.items.len; |
| 504 | try dbg_info_buffer.resize(index + 4); | 507 | try dbg_info_buffer.resize(index + 4); |
| 505 | try self.addTypeRelocGlobal(atom_index, payload_ty, @as(u32, @intCast(index))); | 508 | try self.addTypeRelocGlobal(atom_index, payload_ty, @intCast(index)); |
| 506 | // DW.AT.data_member_location, DW.FORM.udata | 509 | // DW.AT.data_member_location, DW.FORM.udata |
| 507 | try leb128.writeULEB128(dbg_info_buffer.writer(), payload_off); | 510 | try leb128.writeULEB128(dbg_info_buffer.writer(), payload_off); |
| 508 | } | 511 | } |
| ... | @@ -517,7 +520,7 @@ pub const DeclState = struct { | ... | @@ -517,7 +520,7 @@ pub const DeclState = struct { |
| 517 | // DW.AT.type, DW.FORM.ref4 | 520 | // DW.AT.type, DW.FORM.ref4 |
| 518 | const index = dbg_info_buffer.items.len; | 521 | const index = dbg_info_buffer.items.len; |
| 519 | try dbg_info_buffer.resize(index + 4); | 522 | try dbg_info_buffer.resize(index + 4); |
| 520 | try self.addTypeRelocGlobal(atom_index, error_ty, @as(u32, @intCast(index))); | 523 | try self.addTypeRelocGlobal(atom_index, error_ty, @intCast(index)); |
| 521 | // DW.AT.data_member_location, DW.FORM.udata | 524 | // DW.AT.data_member_location, DW.FORM.udata |
| 522 | try leb128.writeULEB128(dbg_info_buffer.writer(), error_off); | 525 | try leb128.writeULEB128(dbg_info_buffer.writer(), error_off); |
| 523 | } | 526 | } |
| ... | @@ -581,7 +584,7 @@ pub const DeclState = struct { | ... | @@ -581,7 +584,7 @@ pub const DeclState = struct { |
| 581 | }, | 584 | }, |
| 582 | .register_pair => |regs| { | 585 | .register_pair => |regs| { |
| 583 | const reg_bits = self.mod.getTarget().ptrBitWidth(); | 586 | const reg_bits = self.mod.getTarget().ptrBitWidth(); |
| 584 | const reg_bytes = @as(u8, @intCast(@divExact(reg_bits, 8))); | 587 | const reg_bytes: u8 = @intCast(@divExact(reg_bits, 8)); |
| 585 | const abi_size = ty.abiSize(self.mod); | 588 | const abi_size = ty.abiSize(self.mod); |
| 586 | try dbg_info.ensureUnusedCapacity(10); | 589 | try dbg_info.ensureUnusedCapacity(10); |
| 587 | dbg_info.appendAssumeCapacity(@intFromEnum(AbbrevKind.parameter)); | 590 | dbg_info.appendAssumeCapacity(@intFromEnum(AbbrevKind.parameter)); |
| ... | @@ -658,7 +661,7 @@ pub const DeclState = struct { | ... | @@ -658,7 +661,7 @@ pub const DeclState = struct { |
| 658 | try dbg_info.ensureUnusedCapacity(5 + name_with_null.len); | 661 | try dbg_info.ensureUnusedCapacity(5 + name_with_null.len); |
| 659 | const index = dbg_info.items.len; | 662 | const index = dbg_info.items.len; |
| 660 | try dbg_info.resize(index + 4); // dw.at.type, dw.form.ref4 | 663 | try dbg_info.resize(index + 4); // dw.at.type, dw.form.ref4 |
| 661 | try self.addTypeRelocGlobal(atom_index, ty, @as(u32, @intCast(index))); // DW.AT.type, DW.FORM.ref4 | 664 | try self.addTypeRelocGlobal(atom_index, ty, @intCast(index)); // DW.AT.type, DW.FORM.ref4 |
| 662 | dbg_info.appendSliceAssumeCapacity(name_with_null); // DW.AT.name, DW.FORM.string | 665 | dbg_info.appendSliceAssumeCapacity(name_with_null); // DW.AT.name, DW.FORM.string |
| 663 | } | 666 | } |
| 664 | | 667 | |
| ... | @@ -674,6 +677,7 @@ pub const DeclState = struct { | ... | @@ -674,6 +677,7 @@ pub const DeclState = struct { |
| 674 | const atom_index = self.di_atom_decls.get(owner_decl).?; | 677 | const atom_index = self.di_atom_decls.get(owner_decl).?; |
| 675 | const name_with_null = name.ptr[0 .. name.len + 1]; | 678 | const name_with_null = name.ptr[0 .. name.len + 1]; |
| 676 | try dbg_info.append(@intFromEnum(AbbrevKind.variable)); | 679 | try dbg_info.append(@intFromEnum(AbbrevKind.variable)); |
| | 680 | const gpa = self.dwarf.allocator; |
| 677 | const mod = self.mod; | 681 | const mod = self.mod; |
| 678 | const target = mod.getTarget(); | 682 | const target = mod.getTarget(); |
| 679 | const endian = target.cpu.arch.endian(); | 683 | const endian = target.cpu.arch.endian(); |
| ... | @@ -701,7 +705,7 @@ pub const DeclState = struct { | ... | @@ -701,7 +705,7 @@ pub const DeclState = struct { |
| 701 | | 705 | |
| 702 | .register_pair => |regs| { | 706 | .register_pair => |regs| { |
| 703 | const reg_bits = self.mod.getTarget().ptrBitWidth(); | 707 | const reg_bits = self.mod.getTarget().ptrBitWidth(); |
| 704 | const reg_bytes = @as(u8, @intCast(@divExact(reg_bits, 8))); | 708 | const reg_bytes: u8 = @intCast(@divExact(reg_bits, 8)); |
| 705 | const abi_size = child_ty.abiSize(self.mod); | 709 | const abi_size = child_ty.abiSize(self.mod); |
| 706 | try dbg_info.ensureUnusedCapacity(9); | 710 | try dbg_info.ensureUnusedCapacity(9); |
| 707 | // DW.AT.location, DW.FORM.exprloc | 711 | // DW.AT.location, DW.FORM.exprloc |
| ... | @@ -775,20 +779,20 @@ pub const DeclState = struct { | ... | @@ -775,20 +779,20 @@ pub const DeclState = struct { |
| 775 | .memory, | 779 | .memory, |
| 776 | .linker_load, | 780 | .linker_load, |
| 777 | => { | 781 | => { |
| 778 | const ptr_width = @as(u8, @intCast(@divExact(target.ptrBitWidth(), 8))); | 782 | const ptr_width: u8 = @intCast(@divExact(target.ptrBitWidth(), 8)); |
| 779 | try dbg_info.ensureUnusedCapacity(2 + ptr_width); | 783 | try dbg_info.ensureUnusedCapacity(2 + ptr_width); |
| 780 | dbg_info.appendSliceAssumeCapacity(&[2]u8{ // DW.AT.location, DW.FORM.exprloc | 784 | dbg_info.appendSliceAssumeCapacity(&[2]u8{ // DW.AT.location, DW.FORM.exprloc |
| 781 | 1 + ptr_width + @intFromBool(is_ptr), | 785 | 1 + ptr_width + @intFromBool(is_ptr), |
| 782 | DW.OP.addr, // literal address | 786 | DW.OP.addr, // literal address |
| 783 | }); | 787 | }); |
| 784 | const offset = @as(u32, @intCast(dbg_info.items.len)); | 788 | const offset: u32 = @intCast(dbg_info.items.len); |
| 785 | const addr = switch (loc) { | 789 | const addr = switch (loc) { |
| 786 | .memory => |x| x, | 790 | .memory => |x| x, |
| 787 | else => 0, | 791 | else => 0, |
| 788 | }; | 792 | }; |
| 789 | switch (ptr_width) { | 793 | switch (ptr_width) { |
| 790 | 0...4 => { | 794 | 0...4 => { |
| 791 | try dbg_info.writer().writeInt(u32, @as(u32, @intCast(addr)), endian); | 795 | try dbg_info.writer().writeInt(u32, @intCast(addr), endian); |
| 792 | }, | 796 | }, |
| 793 | 5...8 => { | 797 | 5...8 => { |
| 794 | try dbg_info.writer().writeInt(u64, addr, endian); | 798 | try dbg_info.writer().writeInt(u64, addr, endian); |
| ... | @@ -803,7 +807,7 @@ pub const DeclState = struct { | ... | @@ -803,7 +807,7 @@ pub const DeclState = struct { |
| 803 | .linker_load => |load_struct| switch (load_struct.type) { | 807 | .linker_load => |load_struct| switch (load_struct.type) { |
| 804 | .direct => { | 808 | .direct => { |
| 805 | log.debug("{x}: target sym %{d}", .{ offset, load_struct.sym_index }); | 809 | log.debug("{x}: target sym %{d}", .{ offset, load_struct.sym_index }); |
| 806 | try self.exprloc_relocs.append(self.gpa, .{ | 810 | try self.exprloc_relocs.append(gpa, .{ |
| 807 | .type = .direct_load, | 811 | .type = .direct_load, |
| 808 | .target = load_struct.sym_index, | 812 | .target = load_struct.sym_index, |
| 809 | .offset = offset, | 813 | .offset = offset, |
| ... | @@ -811,7 +815,7 @@ pub const DeclState = struct { | ... | @@ -811,7 +815,7 @@ pub const DeclState = struct { |
| 811 | }, | 815 | }, |
| 812 | .got => { | 816 | .got => { |
| 813 | log.debug("{x}: target sym %{d} via GOT", .{ offset, load_struct.sym_index }); | 817 | log.debug("{x}: target sym %{d} via GOT", .{ offset, load_struct.sym_index }); |
| 814 | try self.exprloc_relocs.append(self.gpa, .{ | 818 | try self.exprloc_relocs.append(gpa, .{ |
| 815 | .type = .got_load, | 819 | .type = .got_load, |
| 816 | .target = load_struct.sym_index, | 820 | .target = load_struct.sym_index, |
| 817 | .offset = offset, | 821 | .offset = offset, |
| ... | @@ -836,15 +840,15 @@ pub const DeclState = struct { | ... | @@ -836,15 +840,15 @@ pub const DeclState = struct { |
| 836 | try leb128.writeULEB128(dbg_info.writer(), x); | 840 | try leb128.writeULEB128(dbg_info.writer(), x); |
| 837 | } | 841 | } |
| 838 | try dbg_info.append(DW.OP.stack_value); | 842 | try dbg_info.append(DW.OP.stack_value); |
| 839 | dbg_info.items[fixup] += @as(u8, @intCast(dbg_info.items.len - fixup - 2)); | 843 | dbg_info.items[fixup] += @intCast(dbg_info.items.len - fixup - 2); |
| 840 | }, | 844 | }, |
| 841 | | 845 | |
| 842 | .undef => { | 846 | .undef => { |
| 843 | // DW.AT.location, DW.FORM.exprloc | 847 | // DW.AT.location, DW.FORM.exprloc |
| 844 | // uleb128(exprloc_len) | 848 | // uleb128(exprloc_len) |
| 845 | // DW.OP.implicit_value uleb128(len_of_bytes) bytes | 849 | // DW.OP.implicit_value uleb128(len_of_bytes) bytes |
| 846 | const abi_size = @as(u32, @intCast(child_ty.abiSize(mod))); | 850 | const abi_size: u32 = @intCast(child_ty.abiSize(mod)); |
| 847 | var implicit_value_len = std.ArrayList(u8).init(self.gpa); | 851 | var implicit_value_len = std.ArrayList(u8).init(gpa); |
| 848 | defer implicit_value_len.deinit(); | 852 | defer implicit_value_len.deinit(); |
| 849 | try leb128.writeULEB128(implicit_value_len.writer(), abi_size); | 853 | try leb128.writeULEB128(implicit_value_len.writer(), abi_size); |
| 850 | const total_exprloc_len = 1 + implicit_value_len.items.len + abi_size; | 854 | const total_exprloc_len = 1 + implicit_value_len.items.len + abi_size; |
| ... | @@ -873,27 +877,55 @@ pub const DeclState = struct { | ... | @@ -873,27 +877,55 @@ pub const DeclState = struct { |
| 873 | try dbg_info.ensureUnusedCapacity(5 + name_with_null.len); | 877 | try dbg_info.ensureUnusedCapacity(5 + name_with_null.len); |
| 874 | const index = dbg_info.items.len; | 878 | const index = dbg_info.items.len; |
| 875 | try dbg_info.resize(index + 4); // dw.at.type, dw.form.ref4 | 879 | try dbg_info.resize(index + 4); // dw.at.type, dw.form.ref4 |
| 876 | try self.addTypeRelocGlobal(atom_index, child_ty, @as(u32, @intCast(index))); | 880 | try self.addTypeRelocGlobal(atom_index, child_ty, @intCast(index)); |
| 877 | dbg_info.appendSliceAssumeCapacity(name_with_null); // DW.AT.name, DW.FORM.string | 881 | dbg_info.appendSliceAssumeCapacity(name_with_null); // DW.AT.name, DW.FORM.string |
| 878 | } | 882 | } |
| 879 | | 883 | |
| 880 | pub fn advancePCAndLine( | 884 | pub fn advancePCAndLine( |
| 881 | self: *DeclState, | 885 | self: *DeclState, |
| 882 | delta_line: i32, | 886 | delta_line: i33, |
| 883 | delta_pc: usize, | 887 | delta_pc: u64, |
| 884 | ) error{OutOfMemory}!void { | 888 | ) error{OutOfMemory}!void { |
| 885 | // TODO Look into using the DWARF special opcodes to compress this data. | | |
| 886 | // It lets you emit single-byte opcodes that add different numbers to | | |
| 887 | // both the PC and the line number at the same time. | | |
| 888 | const dbg_line = &self.dbg_line; | 889 | const dbg_line = &self.dbg_line; |
| 889 | try dbg_line.ensureUnusedCapacity(11); | 890 | try dbg_line.ensureUnusedCapacity(5 + 5 + 1); |
| 890 | dbg_line.appendAssumeCapacity(DW.LNS.advance_pc); | 891 | |
| 891 | leb128.writeULEB128(dbg_line.writer(), delta_pc) catch unreachable; | 892 | const header = self.dwarf.dbg_line_header; |
| 892 | if (delta_line != 0) { | 893 | assert(header.maximum_operations_per_instruction == 1); |
| | 894 | const delta_op: u64 = 0; |
| | 895 | |
| | 896 | const remaining_delta_line: i9 = @intCast(if (delta_line < header.line_base or |
| | 897 | delta_line - header.line_base >= header.line_range) |
| | 898 | remaining: { |
| | 899 | assert(delta_line != 0); |
| 893 | dbg_line.appendAssumeCapacity(DW.LNS.advance_line); | 900 | dbg_line.appendAssumeCapacity(DW.LNS.advance_line); |
| 894 | leb128.writeILEB128(dbg_line.writer(), delta_line) catch unreachable; | 901 | leb128.writeILEB128(dbg_line.writer(), delta_line) catch unreachable; |
| | 902 | break :remaining 0; |
| | 903 | } else delta_line); |
| | 904 | |
| | 905 | const op_advance = @divExact(delta_pc, header.minimum_instruction_length) * |
| | 906 | header.maximum_operations_per_instruction + delta_op; |
| | 907 | const max_op_advance: u9 = (std.math.maxInt(u8) - header.opcode_base) / header.line_range; |
| | 908 | const remaining_op_advance: u8 = @intCast(if (op_advance >= 2 * max_op_advance) remaining: { |
| | 909 | dbg_line.appendAssumeCapacity(DW.LNS.advance_pc); |
| | 910 | leb128.writeULEB128(dbg_line.writer(), op_advance) catch unreachable; |
| | 911 | break :remaining 0; |
| | 912 | } else if (op_advance >= max_op_advance) remaining: { |
| | 913 | dbg_line.appendAssumeCapacity(DW.LNS.const_add_pc); |
| | 914 | break :remaining op_advance - max_op_advance; |
| | 915 | } else op_advance); |
| | 916 | |
| | 917 | if (remaining_delta_line == 0 and remaining_op_advance == 0) { |
| | 918 | dbg_line.appendAssumeCapacity(DW.LNS.copy); |
| | 919 | } else { |
| | 920 | dbg_line.appendAssumeCapacity(@intCast((remaining_delta_line - header.line_base) + |
| | 921 | (header.line_range * remaining_op_advance) + header.opcode_base)); |
| 895 | } | 922 | } |
| 896 | dbg_line.appendAssumeCapacity(DW.LNS.copy); | 923 | } |
| | 924 | |
| | 925 | pub fn setColumn(self: *DeclState, column: u32) error{OutOfMemory}!void { |
| | 926 | try self.dbg_line.ensureUnusedCapacity(1 + 5); |
| | 927 | self.dbg_line.appendAssumeCapacity(DW.LNS.set_column); |
| | 928 | leb128.writeULEB128(self.dbg_line.writer(), column + 1) catch unreachable; |
| 897 | } | 929 | } |
| 898 | | 930 | |
| 899 | pub fn setPrologueEnd(self: *DeclState) error{OutOfMemory}!void { | 931 | pub fn setPrologueEnd(self: *DeclState) error{OutOfMemory}!void { |
| ... | @@ -903,6 +935,31 @@ pub const DeclState = struct { | ... | @@ -903,6 +935,31 @@ pub const DeclState = struct { |
| 903 | pub fn setEpilogueBegin(self: *DeclState) error{OutOfMemory}!void { | 935 | pub fn setEpilogueBegin(self: *DeclState) error{OutOfMemory}!void { |
| 904 | try self.dbg_line.append(DW.LNS.set_epilogue_begin); | 936 | try self.dbg_line.append(DW.LNS.set_epilogue_begin); |
| 905 | } | 937 | } |
| | 938 | |
| | 939 | pub fn setInlineFunc(self: *DeclState, func: InternPool.Index) error{OutOfMemory}!void { |
| | 940 | if (self.dbg_line_func == func) return; |
| | 941 | |
| | 942 | try self.dbg_line.ensureUnusedCapacity((1 + 4) + (1 + 5)); |
| | 943 | |
| | 944 | const old_func_info = self.mod.funcInfo(self.dbg_line_func); |
| | 945 | const new_func_info = self.mod.funcInfo(func); |
| | 946 | |
| | 947 | const old_file = try self.dwarf.addDIFile(self.mod, old_func_info.owner_decl); |
| | 948 | const new_file = try self.dwarf.addDIFile(self.mod, new_func_info.owner_decl); |
| | 949 | if (old_file != new_file) { |
| | 950 | self.dbg_line.appendAssumeCapacity(DW.LNS.set_file); |
| | 951 | leb128.writeUnsignedFixed(4, self.dbg_line.addManyAsArrayAssumeCapacity(4), new_file); |
| | 952 | } |
| | 953 | |
| | 954 | const old_src_line: i33 = self.mod.declPtr(old_func_info.owner_decl).src_line; |
| | 955 | const new_src_line: i33 = self.mod.declPtr(new_func_info.owner_decl).src_line; |
| | 956 | if (new_src_line != old_src_line) { |
| | 957 | self.dbg_line.appendAssumeCapacity(DW.LNS.advance_line); |
| | 958 | leb128.writeSignedFixed(5, self.dbg_line.addManyAsArrayAssumeCapacity(5), new_src_line - old_src_line); |
| | 959 | } |
| | 960 | |
| | 961 | self.dbg_line_func = func; |
| | 962 | } |
| 906 | }; | 963 | }; |
| 907 | | 964 | |
| 908 | pub const AbbrevEntry = struct { | 965 | pub const AbbrevEntry = struct { |
| ... | @@ -966,7 +1023,8 @@ const min_nop_size = 2; | ... | @@ -966,7 +1023,8 @@ const min_nop_size = 2; |
| 966 | const ideal_factor = 3; | 1023 | const ideal_factor = 3; |
| 967 | | 1024 | |
| 968 | pub fn init(allocator: Allocator, bin_file: *File, format: Format) Dwarf { | 1025 | pub fn init(allocator: Allocator, bin_file: *File, format: Format) Dwarf { |
| 969 | const ptr_width: PtrWidth = switch (bin_file.options.target.ptrBitWidth()) { | 1026 | const target = &bin_file.options.target; |
| | 1027 | const ptr_width: PtrWidth = switch (target.ptrBitWidth()) { |
| 970 | 0...32 => .p32, | 1028 | 0...32 => .p32, |
| 971 | 33...64 => .p64, | 1029 | 33...64 => .p64, |
| 972 | else => unreachable, | 1030 | else => unreachable, |
| ... | @@ -976,6 +1034,24 @@ pub fn init(allocator: Allocator, bin_file: *File, format: Format) Dwarf { | ... | @@ -976,6 +1034,24 @@ pub fn init(allocator: Allocator, bin_file: *File, format: Format) Dwarf { |
| 976 | .bin_file = bin_file, | 1034 | .bin_file = bin_file, |
| 977 | .format = format, | 1035 | .format = format, |
| 978 | .ptr_width = ptr_width, | 1036 | .ptr_width = ptr_width, |
| | 1037 | .dbg_line_header = switch (target.cpu.arch) { |
| | 1038 | .x86_64 => .{ |
| | 1039 | .minimum_instruction_length = 1, |
| | 1040 | .maximum_operations_per_instruction = 1, |
| | 1041 | .default_is_stmt = true, |
| | 1042 | .line_base = -5, |
| | 1043 | .line_range = 14, |
| | 1044 | .opcode_base = DW.LNS.set_isa + 1, |
| | 1045 | }, |
| | 1046 | else => .{ |
| | 1047 | .minimum_instruction_length = 1, |
| | 1048 | .maximum_operations_per_instruction = 1, |
| | 1049 | .default_is_stmt = true, |
| | 1050 | .line_base = 1, |
| | 1051 | .line_range = 1, |
| | 1052 | .opcode_base = DW.LNS.set_isa + 1, |
| | 1053 | }, |
| | 1054 | }, |
| 979 | }; | 1055 | }; |
| 980 | } | 1056 | } |
| 981 | | 1057 | |
| ... | @@ -1002,12 +1078,24 @@ pub fn initDeclState(self: *Dwarf, mod: *Module, decl_index: Module.Decl.Index) | ... | @@ -1002,12 +1078,24 @@ pub fn initDeclState(self: *Dwarf, mod: *Module, decl_index: Module.Decl.Index) |
| 1002 | defer tracy.end(); | 1078 | defer tracy.end(); |
| 1003 | | 1079 | |
| 1004 | const decl = mod.declPtr(decl_index); | 1080 | const decl = mod.declPtr(decl_index); |
| 1005 | const decl_name = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod)); | 1081 | const decl_linkage_name = try decl.getFullyQualifiedName(mod); |
| 1006 | | 1082 | |
| 1007 | log.debug("initDeclState {s}{*}", .{ decl_name, decl }); | 1083 | log.debug("initDeclState {}{*}", .{ decl_linkage_name.fmt(&mod.intern_pool), decl }); |
| 1008 | | 1084 | |
| 1009 | const gpa = self.allocator; | 1085 | const gpa = self.allocator; |
| 1010 | var decl_state = DeclState.init(gpa, mod, &self.di_atom_decls); | 1086 | var decl_state: DeclState = .{ |
| | 1087 | .dwarf = self, |
| | 1088 | .mod = mod, |
| | 1089 | .di_atom_decls = &self.di_atom_decls, |
| | 1090 | .dbg_line_func = undefined, |
| | 1091 | .dbg_line = std.ArrayList(u8).init(gpa), |
| | 1092 | .dbg_info = std.ArrayList(u8).init(gpa), |
| | 1093 | .abbrev_type_arena = std.heap.ArenaAllocator.init(gpa), |
| | 1094 | .abbrev_table = .{}, |
| | 1095 | .abbrev_resolver = .{}, |
| | 1096 | .abbrev_relocs = .{}, |
| | 1097 | .exprloc_relocs = .{}, |
| | 1098 | }; |
| 1011 | errdefer decl_state.deinit(); | 1099 | errdefer decl_state.deinit(); |
| 1012 | const dbg_line_buffer = &decl_state.dbg_line; | 1100 | const dbg_line_buffer = &decl_state.dbg_line; |
| 1013 | const dbg_info_buffer = &decl_state.dbg_info; | 1101 | const dbg_info_buffer = &decl_state.dbg_info; |
| ... | @@ -1021,18 +1109,19 @@ pub fn initDeclState(self: *Dwarf, mod: *Module, decl_index: Module.Decl.Index) | ... | @@ -1021,18 +1109,19 @@ pub fn initDeclState(self: *Dwarf, mod: *Module, decl_index: Module.Decl.Index) |
| 1021 | _ = try self.getOrCreateAtomForDecl(.src_fn, decl_index); | 1109 | _ = try self.getOrCreateAtomForDecl(.src_fn, decl_index); |
| 1022 | | 1110 | |
| 1023 | // For functions we need to add a prologue to the debug line program. | 1111 | // For functions we need to add a prologue to the debug line program. |
| 1024 | try dbg_line_buffer.ensureTotalCapacity(26); | 1112 | const ptr_width_bytes = self.ptrWidthBytes(); |
| | 1113 | try dbg_line_buffer.ensureTotalCapacity((3 + ptr_width_bytes) + (1 + 4) + (1 + 4) + (1 + 5) + 1); |
| 1025 | | 1114 | |
| | 1115 | decl_state.dbg_line_func = decl.val.toIntern(); |
| 1026 | const func = decl.val.getFunction(mod).?; | 1116 | const func = decl.val.getFunction(mod).?; |
| 1027 | log.debug("decl.src_line={d}, func.lbrace_line={d}, func.rbrace_line={d}", .{ | 1117 | log.debug("decl.src_line={d}, func.lbrace_line={d}, func.rbrace_line={d}", .{ |
| 1028 | decl.src_line, | 1118 | decl.src_line, |
| 1029 | func.lbrace_line, | 1119 | func.lbrace_line, |
| 1030 | func.rbrace_line, | 1120 | func.rbrace_line, |
| 1031 | }); | 1121 | }); |
| 1032 | const line = @as(u28, @intCast(decl.src_line + func.lbrace_line)); | 1122 | const line: u28 = @intCast(decl.src_line + func.lbrace_line); |
| 1033 | | 1123 | |
| 1034 | const ptr_width_bytes = self.ptrWidthBytes(); | 1124 | dbg_line_buffer.appendSliceAssumeCapacity(&.{ |
| 1035 | dbg_line_buffer.appendSliceAssumeCapacity(&[_]u8{ | | |
| 1036 | DW.LNS.extended_op, | 1125 | DW.LNS.extended_op, |
| 1037 | ptr_width_bytes + 1, | 1126 | ptr_width_bytes + 1, |
| 1038 | DW.LNE.set_address, | 1127 | DW.LNE.set_address, |
| ... | @@ -1055,21 +1144,24 @@ pub fn initDeclState(self: *Dwarf, mod: *Module, decl_index: Module.Decl.Index) | ... | @@ -1055,21 +1144,24 @@ pub fn initDeclState(self: *Dwarf, mod: *Module, decl_index: Module.Decl.Index) |
| 1055 | const file_index = try self.addDIFile(mod, decl_index); | 1144 | const file_index = try self.addDIFile(mod, decl_index); |
| 1056 | leb128.writeUnsignedFixed(4, dbg_line_buffer.addManyAsArrayAssumeCapacity(4), file_index); | 1145 | leb128.writeUnsignedFixed(4, dbg_line_buffer.addManyAsArrayAssumeCapacity(4), file_index); |
| 1057 | | 1146 | |
| | 1147 | dbg_line_buffer.appendAssumeCapacity(DW.LNS.set_column); |
| | 1148 | leb128.writeULEB128(dbg_line_buffer.writer(), func.lbrace_column + 1) catch unreachable; |
| | 1149 | |
| 1058 | // Emit a line for the begin curly with prologue_end=false. The codegen will | 1150 | // Emit a line for the begin curly with prologue_end=false. The codegen will |
| 1059 | // do the work of setting prologue_end=true and epilogue_begin=true. | 1151 | // do the work of setting prologue_end=true and epilogue_begin=true. |
| 1060 | dbg_line_buffer.appendAssumeCapacity(DW.LNS.copy); | 1152 | dbg_line_buffer.appendAssumeCapacity(DW.LNS.copy); |
| 1061 | | 1153 | |
| 1062 | // .debug_info subprogram | 1154 | // .debug_info subprogram |
| 1063 | const decl_name_with_null = decl_name[0 .. decl_name.len + 1]; | 1155 | const decl_name_slice = mod.intern_pool.stringToSlice(decl.name); |
| 1064 | try dbg_info_buffer.ensureUnusedCapacity(25 + decl_name_with_null.len); | 1156 | const decl_linkage_name_slice = mod.intern_pool.stringToSlice(decl_linkage_name); |
| | 1157 | try dbg_info_buffer.ensureUnusedCapacity(1 + ptr_width_bytes + 4 + 4 + |
| | 1158 | (decl_name_slice.len + 1) + (decl_linkage_name_slice.len + 1)); |
| 1065 | | 1159 | |
| 1066 | const fn_ret_type = decl.ty.fnReturnType(mod); | 1160 | const fn_ret_type = decl.ty.fnReturnType(mod); |
| 1067 | const fn_ret_has_bits = fn_ret_type.hasRuntimeBits(mod); | 1161 | const fn_ret_has_bits = fn_ret_type.hasRuntimeBits(mod); |
| 1068 | if (fn_ret_has_bits) { | 1162 | dbg_info_buffer.appendAssumeCapacity(@intFromEnum( |
| 1069 | dbg_info_buffer.appendAssumeCapacity(@intFromEnum(AbbrevKind.subprogram)); | 1163 | @as(AbbrevKind, if (fn_ret_has_bits) .subprogram else .subprogram_retvoid), |
| 1070 | } else { | 1164 | )); |
| 1071 | dbg_info_buffer.appendAssumeCapacity(@intFromEnum(AbbrevKind.subprogram_retvoid)); | | |
| 1072 | } | | |
| 1073 | // These get overwritten after generating the machine code. These values are | 1165 | // These get overwritten after generating the machine code. These values are |
| 1074 | // "relocations" and have to be in this fixed place so that functions can be | 1166 | // "relocations" and have to be in this fixed place so that functions can be |
| 1075 | // moved in virtual address space. | 1167 | // moved in virtual address space. |
| ... | @@ -1077,14 +1169,16 @@ pub fn initDeclState(self: *Dwarf, mod: *Module, decl_index: Module.Decl.Index) | ... | @@ -1077,14 +1169,16 @@ pub fn initDeclState(self: *Dwarf, mod: *Module, decl_index: Module.Decl.Index) |
| 1077 | dbg_info_buffer.items.len += ptr_width_bytes; // DW.AT.low_pc, DW.FORM.addr | 1169 | dbg_info_buffer.items.len += ptr_width_bytes; // DW.AT.low_pc, DW.FORM.addr |
| 1078 | assert(self.getRelocDbgInfoSubprogramHighPC() == dbg_info_buffer.items.len); | 1170 | assert(self.getRelocDbgInfoSubprogramHighPC() == dbg_info_buffer.items.len); |
| 1079 | dbg_info_buffer.items.len += 4; // DW.AT.high_pc, DW.FORM.data4 | 1171 | dbg_info_buffer.items.len += 4; // DW.AT.high_pc, DW.FORM.data4 |
| 1080 | // | | |
| 1081 | if (fn_ret_has_bits) { | 1172 | if (fn_ret_has_bits) { |
| 1082 | try decl_state.addTypeRelocGlobal(di_atom_index, fn_ret_type, @as(u32, @intCast(dbg_info_buffer.items.len))); | 1173 | try decl_state.addTypeRelocGlobal(di_atom_index, fn_ret_type, @intCast(dbg_info_buffer.items.len)); |
| 1083 | dbg_info_buffer.items.len += 4; // DW.AT.type, DW.FORM.ref4 | 1174 | dbg_info_buffer.items.len += 4; // DW.AT.type, DW.FORM.ref4 |
| 1084 | } | 1175 | } |
| 1085 | | 1176 | dbg_info_buffer.appendSliceAssumeCapacity( |
| 1086 | dbg_info_buffer.appendSliceAssumeCapacity(decl_name_with_null); // DW.AT.name, DW.FORM.string | 1177 | decl_name_slice[0 .. decl_name_slice.len + 1], |
| 1087 | | 1178 | ); // DW.AT.name, DW.FORM.string |
| | 1179 | dbg_info_buffer.appendSliceAssumeCapacity( |
| | 1180 | decl_linkage_name_slice[0 .. decl_linkage_name_slice.len + 1], |
| | 1181 | ); // DW.AT.linkage_name, DW.FORM.string |
| 1088 | }, | 1182 | }, |
| 1089 | else => { | 1183 | else => { |
| 1090 | // TODO implement .debug_info for global variables | 1184 | // TODO implement .debug_info for global variables |
| ... | @@ -1116,17 +1210,19 @@ pub fn commitDeclState( | ... | @@ -1116,17 +1210,19 @@ pub fn commitDeclState( |
| 1116 | assert(decl.has_tv); | 1210 | assert(decl.has_tv); |
| 1117 | switch (decl.ty.zigTypeTag(mod)) { | 1211 | switch (decl.ty.zigTypeTag(mod)) { |
| 1118 | .Fn => { | 1212 | .Fn => { |
| | 1213 | try decl_state.setInlineFunc(decl.val.toIntern()); |
| | 1214 | |
| 1119 | // Since the Decl is a function, we need to update the .debug_line program. | 1215 | // Since the Decl is a function, we need to update the .debug_line program. |
| 1120 | // Perform the relocations based on vaddr. | 1216 | // Perform the relocations based on vaddr. |
| 1121 | switch (self.ptr_width) { | 1217 | switch (self.ptr_width) { |
| 1122 | .p32 => { | 1218 | .p32 => { |
| 1123 | { | 1219 | { |
| 1124 | const ptr = dbg_line_buffer.items[dbg_line_vaddr_reloc_index..][0..4]; | 1220 | const ptr = dbg_line_buffer.items[dbg_line_vaddr_reloc_index..][0..4]; |
| 1125 | mem.writeInt(u32, ptr, @as(u32, @intCast(sym_addr)), target_endian); | 1221 | mem.writeInt(u32, ptr, @intCast(sym_addr), target_endian); |
| 1126 | } | 1222 | } |
| 1127 | { | 1223 | { |
| 1128 | const ptr = dbg_info_buffer.items[dbg_info_low_pc_reloc_index..][0..4]; | 1224 | const ptr = dbg_info_buffer.items[dbg_info_low_pc_reloc_index..][0..4]; |
| 1129 | mem.writeInt(u32, ptr, @as(u32, @intCast(sym_addr)), target_endian); | 1225 | mem.writeInt(u32, ptr, @intCast(sym_addr), target_endian); |
| 1130 | } | 1226 | } |
| 1131 | }, | 1227 | }, |
| 1132 | .p64 => { | 1228 | .p64 => { |
| ... | @@ -1146,7 +1242,7 @@ pub fn commitDeclState( | ... | @@ -1146,7 +1242,7 @@ pub fn commitDeclState( |
| 1146 | sym_size, | 1242 | sym_size, |
| 1147 | }); | 1243 | }); |
| 1148 | const ptr = dbg_info_buffer.items[self.getRelocDbgInfoSubprogramHighPC()..][0..4]; | 1244 | const ptr = dbg_info_buffer.items[self.getRelocDbgInfoSubprogramHighPC()..][0..4]; |
| 1149 | mem.writeInt(u32, ptr, @as(u32, @intCast(sym_size)), target_endian); | 1245 | mem.writeInt(u32, ptr, @intCast(sym_size), target_endian); |
| 1150 | } | 1246 | } |
| 1151 | | 1247 | |
| 1152 | try dbg_line_buffer.appendSlice(&[_]u8{ DW.LNS.extended_op, 1, DW.LNE.end_sequence }); | 1248 | try dbg_line_buffer.appendSlice(&[_]u8{ DW.LNS.extended_op, 1, DW.LNE.end_sequence }); |
| ... | @@ -1158,7 +1254,7 @@ pub fn commitDeclState( | ... | @@ -1158,7 +1254,7 @@ pub fn commitDeclState( |
| 1158 | // probably need to edit that logic too. | 1254 | // probably need to edit that logic too. |
| 1159 | const src_fn_index = self.src_fn_decls.get(decl_index).?; | 1255 | const src_fn_index = self.src_fn_decls.get(decl_index).?; |
| 1160 | const src_fn = self.getAtomPtr(.src_fn, src_fn_index); | 1256 | const src_fn = self.getAtomPtr(.src_fn, src_fn_index); |
| 1161 | src_fn.len = @as(u32, @intCast(dbg_line_buffer.items.len)); | 1257 | src_fn.len = @intCast(dbg_line_buffer.items.len); |
| 1162 | | 1258 | |
| 1163 | if (self.src_fn_last_index) |last_index| blk: { | 1259 | if (self.src_fn_last_index) |last_index| blk: { |
| 1164 | if (src_fn_index == last_index) break :blk; | 1260 | if (src_fn_index == last_index) break :blk; |
| ... | @@ -1315,7 +1411,7 @@ pub fn commitDeclState( | ... | @@ -1315,7 +1411,7 @@ pub fn commitDeclState( |
| 1315 | } | 1411 | } |
| 1316 | } | 1412 | } |
| 1317 | | 1413 | |
| 1318 | try self.updateDeclDebugInfoAllocation(di_atom_index, @as(u32, @intCast(dbg_info_buffer.items.len))); | 1414 | try self.updateDeclDebugInfoAllocation(di_atom_index, @intCast(dbg_info_buffer.items.len)); |
| 1319 | | 1415 | |
| 1320 | while (decl_state.abbrev_relocs.popOrNull()) |reloc| { | 1416 | while (decl_state.abbrev_relocs.popOrNull()) |reloc| { |
| 1321 | if (reloc.target) |target| { | 1417 | if (reloc.target) |target| { |
| ... | @@ -1448,7 +1544,7 @@ fn updateDeclDebugInfoAllocation(self: *Dwarf, atom_index: Atom.Index, len: u32) | ... | @@ -1448,7 +1544,7 @@ fn updateDeclDebugInfoAllocation(self: *Dwarf, atom_index: Atom.Index, len: u32) |
| 1448 | self.di_atom_first_index = atom_index; | 1544 | self.di_atom_first_index = atom_index; |
| 1449 | self.di_atom_last_index = atom_index; | 1545 | self.di_atom_last_index = atom_index; |
| 1450 | | 1546 | |
| 1451 | atom.off = @as(u32, @intCast(padToIdeal(self.dbgInfoHeaderBytes()))); | 1547 | atom.off = @intCast(padToIdeal(self.dbgInfoHeaderBytes())); |
| 1452 | } | 1548 | } |
| 1453 | } | 1549 | } |
| 1454 | | 1550 | |
| ... | @@ -1559,7 +1655,7 @@ pub fn updateDeclLineNumber(self: *Dwarf, mod: *Module, decl_index: Module.Decl. | ... | @@ -1559,7 +1655,7 @@ pub fn updateDeclLineNumber(self: *Dwarf, mod: *Module, decl_index: Module.Decl. |
| 1559 | func.lbrace_line, | 1655 | func.lbrace_line, |
| 1560 | func.rbrace_line, | 1656 | func.rbrace_line, |
| 1561 | }); | 1657 | }); |
| 1562 | const line = @as(u28, @intCast(decl.src_line + func.lbrace_line)); | 1658 | const line: u28 = @intCast(decl.src_line + func.lbrace_line); |
| 1563 | var data: [4]u8 = undefined; | 1659 | var data: [4]u8 = undefined; |
| 1564 | leb128.writeUnsignedFixed(4, &data, line); | 1660 | leb128.writeUnsignedFixed(4, &data, line); |
| 1565 | | 1661 | |
| ... | @@ -1647,131 +1743,122 @@ pub fn freeDecl(self: *Dwarf, decl_index: Module.Decl.Index) void { | ... | @@ -1647,131 +1743,122 @@ pub fn freeDecl(self: *Dwarf, decl_index: Module.Decl.Index) void { |
| 1647 | pub fn writeDbgAbbrev(self: *Dwarf) !void { | 1743 | pub fn writeDbgAbbrev(self: *Dwarf) !void { |
| 1648 | // These are LEB encoded but since the values are all less than 127 | 1744 | // These are LEB encoded but since the values are all less than 127 |
| 1649 | // we can simply append these bytes. | 1745 | // we can simply append these bytes. |
| | 1746 | // zig fmt: off |
| 1650 | const abbrev_buf = [_]u8{ | 1747 | const abbrev_buf = [_]u8{ |
| 1651 | @intFromEnum(AbbrevKind.compile_unit), DW.TAG.compile_unit, DW.CHILDREN.yes, // header | 1748 | @intFromEnum(AbbrevKind.compile_unit), |
| 1652 | DW.AT.stmt_list, DW.FORM.sec_offset, DW.AT.low_pc, | 1749 | DW.TAG.compile_unit, |
| 1653 | DW.FORM.addr, DW.AT.high_pc, DW.FORM.addr, | 1750 | DW.CHILDREN.yes, |
| 1654 | DW.AT.name, DW.FORM.strp, DW.AT.comp_dir, | 1751 | DW.AT.stmt_list, DW.FORM.sec_offset, |
| 1655 | DW.FORM.strp, DW.AT.producer, DW.FORM.strp, | 1752 | DW.AT.low_pc, DW.FORM.addr, |
| 1656 | DW.AT.language, DW.FORM.data2, 0, | 1753 | DW.AT.high_pc, DW.FORM.addr, |
| 1657 | 0, // table sentinel | 1754 | DW.AT.name, DW.FORM.strp, |
| | 1755 | DW.AT.comp_dir, DW.FORM.strp, |
| | 1756 | DW.AT.producer, DW.FORM.strp, |
| | 1757 | DW.AT.language, DW.FORM.data2, |
| | 1758 | 0, 0, |
| | 1759 | |
| 1658 | @intFromEnum(AbbrevKind.subprogram), | 1760 | @intFromEnum(AbbrevKind.subprogram), |
| 1659 | DW.TAG.subprogram, | 1761 | DW.TAG.subprogram, |
| 1660 | DW.CHILDREN.yes, // header | 1762 | DW.CHILDREN.yes, |
| 1661 | DW.AT.low_pc, | 1763 | DW.AT.low_pc, DW.FORM.addr, |
| 1662 | DW.FORM.addr, | 1764 | DW.AT.high_pc, DW.FORM.data4, |
| 1663 | DW.AT.high_pc, | 1765 | DW.AT.type, DW.FORM.ref4, |
| 1664 | DW.FORM.data4, | 1766 | DW.AT.name, DW.FORM.string, |
| 1665 | DW.AT.type, | 1767 | DW.AT.linkage_name, DW.FORM.string, |
| 1666 | DW.FORM.ref4, | 1768 | 0, 0, |
| 1667 | DW.AT.name, | 1769 | |
| 1668 | DW.FORM.string, | | |
| 1669 | 0, 0, // table sentinel | | |
| 1670 | @intFromEnum(AbbrevKind.subprogram_retvoid), | 1770 | @intFromEnum(AbbrevKind.subprogram_retvoid), |
| 1671 | DW.TAG.subprogram, DW.CHILDREN.yes, // header | 1771 | DW.TAG.subprogram, |
| 1672 | DW.AT.low_pc, DW.FORM.addr, | 1772 | DW.CHILDREN.yes, |
| 1673 | DW.AT.high_pc, DW.FORM.data4, | 1773 | DW.AT.low_pc, DW.FORM.addr, |
| 1674 | DW.AT.name, DW.FORM.string, | 1774 | DW.AT.high_pc, DW.FORM.data4, |
| 1675 | 0, | 1775 | DW.AT.name, DW.FORM.string, |
| 1676 | 0, // table sentinel | 1776 | DW.AT.linkage_name, DW.FORM.string, |
| | 1777 | 0, 0, |
| | 1778 | |
| 1677 | @intFromEnum(AbbrevKind.base_type), | 1779 | @intFromEnum(AbbrevKind.base_type), |
| 1678 | DW.TAG.base_type, | 1780 | DW.TAG.base_type, DW.CHILDREN.no, |
| 1679 | DW.CHILDREN.no, // header | 1781 | DW.AT.encoding, DW.FORM.data1, |
| 1680 | DW.AT.encoding, | 1782 | DW.AT.byte_size, DW.FORM.udata, |
| 1681 | DW.FORM.data1, | 1783 | DW.AT.name, DW.FORM.string, |
| 1682 | DW.AT.byte_size, | 1784 | 0, 0, |
| 1683 | DW.FORM.udata, | 1785 | |
| 1684 | DW.AT.name, | | |
| 1685 | DW.FORM.string, | | |
| 1686 | 0, | | |
| 1687 | 0, // table sentinel | | |
| 1688 | @intFromEnum(AbbrevKind.ptr_type), | 1786 | @intFromEnum(AbbrevKind.ptr_type), |
| 1689 | DW.TAG.pointer_type, | 1787 | DW.TAG.pointer_type, DW.CHILDREN.no, |
| 1690 | DW.CHILDREN.no, // header | 1788 | DW.AT.type, DW.FORM.ref4, |
| 1691 | DW.AT.type, | 1789 | 0, 0, |
| 1692 | DW.FORM.ref4, | 1790 | |
| 1693 | 0, | | |
| 1694 | 0, // table sentinel | | |
| 1695 | @intFromEnum(AbbrevKind.struct_type), | 1791 | @intFromEnum(AbbrevKind.struct_type), |
| 1696 | DW.TAG.structure_type, | 1792 | DW.TAG.structure_type, DW.CHILDREN.yes, |
| 1697 | DW.CHILDREN.yes, // header | 1793 | DW.AT.byte_size, DW.FORM.udata, |
| 1698 | DW.AT.byte_size, | 1794 | DW.AT.name, DW.FORM.string, |
| 1699 | DW.FORM.udata, | 1795 | 0, 0, |
| 1700 | DW.AT.name, | 1796 | |
| 1701 | DW.FORM.string, | | |
| 1702 | 0, | | |
| 1703 | 0, // table sentinel | | |
| 1704 | @intFromEnum(AbbrevKind.struct_member), | 1797 | @intFromEnum(AbbrevKind.struct_member), |
| 1705 | DW.TAG.member, | 1798 | DW.TAG.member, |
| 1706 | DW.CHILDREN.no, // header | 1799 | DW.CHILDREN.no, |
| 1707 | DW.AT.name, | 1800 | DW.AT.name, DW.FORM.string, |
| 1708 | DW.FORM.string, | 1801 | DW.AT.type, DW.FORM.ref4, |
| 1709 | DW.AT.type, | 1802 | DW.AT.data_member_location, DW.FORM.udata, |
| 1710 | DW.FORM.ref4, | 1803 | 0, 0, |
| 1711 | DW.AT.data_member_location, | 1804 | |
| 1712 | DW.FORM.udata, | | |
| 1713 | 0, | | |
| 1714 | 0, // table sentinel | | |
| 1715 | @intFromEnum(AbbrevKind.enum_type), | 1805 | @intFromEnum(AbbrevKind.enum_type), |
| 1716 | DW.TAG.enumeration_type, | 1806 | DW.TAG.enumeration_type, |
| 1717 | DW.CHILDREN.yes, // header | 1807 | DW.CHILDREN.yes, |
| 1718 | DW.AT.byte_size, | 1808 | DW.AT.byte_size, DW.FORM.udata, |
| 1719 | DW.FORM.udata, | 1809 | DW.AT.name, DW.FORM.string, |
| 1720 | DW.AT.name, | 1810 | 0, 0, |
| 1721 | DW.FORM.string, | 1811 | |
| 1722 | 0, | | |
| 1723 | 0, // table sentinel | | |
| 1724 | @intFromEnum(AbbrevKind.enum_variant), | 1812 | @intFromEnum(AbbrevKind.enum_variant), |
| 1725 | DW.TAG.enumerator, | 1813 | DW.TAG.enumerator, DW.CHILDREN.no, |
| 1726 | DW.CHILDREN.no, // header | 1814 | DW.AT.name, DW.FORM.string, |
| 1727 | DW.AT.name, | 1815 | DW.AT.const_value, DW.FORM.data8, |
| 1728 | DW.FORM.string, | 1816 | 0, 0, |
| 1729 | DW.AT.const_value, | 1817 | |
| 1730 | DW.FORM.data8, | | |
| 1731 | 0, | | |
| 1732 | 0, // table sentinel | | |
| 1733 | @intFromEnum(AbbrevKind.union_type), | 1818 | @intFromEnum(AbbrevKind.union_type), |
| 1734 | DW.TAG.union_type, | 1819 | DW.TAG.union_type, DW.CHILDREN.yes, |
| 1735 | DW.CHILDREN.yes, // header | 1820 | DW.AT.byte_size, DW.FORM.udata, |
| 1736 | DW.AT.byte_size, | 1821 | DW.AT.name, DW.FORM.string, |
| 1737 | DW.FORM.udata, | 1822 | 0, 0, |
| 1738 | DW.AT.name, | 1823 | |
| 1739 | DW.FORM.string, | | |
| 1740 | 0, | | |
| 1741 | 0, // table sentinel | | |
| 1742 | @intFromEnum(AbbrevKind.pad1), | 1824 | @intFromEnum(AbbrevKind.pad1), |
| 1743 | DW.TAG.unspecified_type, | 1825 | DW.TAG.unspecified_type, |
| 1744 | DW.CHILDREN.no, // header | 1826 | DW.CHILDREN.no, |
| 1745 | 0, | 1827 | 0, 0, |
| 1746 | 0, // table sentinel | 1828 | |
| 1747 | @intFromEnum(AbbrevKind.parameter), | 1829 | @intFromEnum(AbbrevKind.parameter), |
| 1748 | DW.TAG.formal_parameter, DW.CHILDREN.no, // header | 1830 | DW.TAG.formal_parameter, |
| 1749 | DW.AT.location, DW.FORM.exprloc, | 1831 | DW.CHILDREN.no, |
| 1750 | DW.AT.type, DW.FORM.ref4, | 1832 | DW.AT.location, DW.FORM.exprloc, |
| 1751 | DW.AT.name, DW.FORM.string, | 1833 | DW.AT.type, DW.FORM.ref4, |
| 1752 | 0, | 1834 | DW.AT.name, DW.FORM.string, |
| 1753 | 0, // table sentinel | 1835 | 0, 0, |
| | 1836 | |
| 1754 | @intFromEnum(AbbrevKind.variable), | 1837 | @intFromEnum(AbbrevKind.variable), |
| 1755 | DW.TAG.variable, DW.CHILDREN.no, // header | 1838 | DW.TAG.variable, |
| 1756 | DW.AT.location, DW.FORM.exprloc, | 1839 | DW.CHILDREN.no, |
| 1757 | DW.AT.type, DW.FORM.ref4, | 1840 | DW.AT.location, DW.FORM.exprloc, |
| 1758 | DW.AT.name, DW.FORM.string, | 1841 | DW.AT.type, DW.FORM.ref4, |
| 1759 | 0, | 1842 | DW.AT.name, DW.FORM.string, |
| 1760 | 0, // table sentinel | 1843 | 0, 0, |
| | 1844 | |
| 1761 | @intFromEnum(AbbrevKind.array_type), | 1845 | @intFromEnum(AbbrevKind.array_type), |
| 1762 | DW.TAG.array_type, DW.CHILDREN.yes, // header | 1846 | DW.TAG.array_type, |
| 1763 | DW.AT.name, DW.FORM.string, | 1847 | DW.CHILDREN.yes, |
| 1764 | DW.AT.type, DW.FORM.ref4, | 1848 | DW.AT.name, DW.FORM.string, |
| 1765 | 0, | 1849 | DW.AT.type, DW.FORM.ref4, |
| 1766 | 0, // table sentinel | 1850 | 0, 0, |
| | 1851 | |
| 1767 | @intFromEnum(AbbrevKind.array_dim), | 1852 | @intFromEnum(AbbrevKind.array_dim), |
| 1768 | DW.TAG.subrange_type, DW.CHILDREN.no, // header | 1853 | DW.TAG.subrange_type, |
| 1769 | DW.AT.type, DW.FORM.ref4, | 1854 | DW.CHILDREN.no, |
| 1770 | DW.AT.count, DW.FORM.udata, | 1855 | DW.AT.type, DW.FORM.ref4, |
| | 1856 | DW.AT.count, DW.FORM.udata, |
| | 1857 | 0, 0, |
| | 1858 | |
| 1771 | 0, | 1859 | 0, |
| 1772 | 0, // table sentinel | | |
| 1773 | 0, // section sentinel | | |
| 1774 | }; | 1860 | }; |
| | 1861 | // zig fmt: on |
| 1775 | const abbrev_offset = 0; | 1862 | const abbrev_offset = 0; |
| 1776 | self.abbrev_table_offset = abbrev_offset; | 1863 | self.abbrev_table_offset = abbrev_offset; |
| 1777 | | 1864 | |
| ... | @@ -1910,7 +1997,7 @@ fn resolveCompilationDir(module: *Module, buffer: *[std.fs.MAX_PATH_BYTES]u8) [] | ... | @@ -1910,7 +1997,7 @@ fn resolveCompilationDir(module: *Module, buffer: *[std.fs.MAX_PATH_BYTES]u8) [] |
| 1910 | fn writeAddrAssumeCapacity(self: *Dwarf, buf: *std.ArrayList(u8), addr: u64) void { | 1997 | fn writeAddrAssumeCapacity(self: *Dwarf, buf: *std.ArrayList(u8), addr: u64) void { |
| 1911 | const target_endian = self.bin_file.options.target.cpu.arch.endian(); | 1998 | const target_endian = self.bin_file.options.target.cpu.arch.endian(); |
| 1912 | switch (self.ptr_width) { | 1999 | switch (self.ptr_width) { |
| 1913 | .p32 => mem.writeInt(u32, buf.addManyAsArrayAssumeCapacity(4), @as(u32, @intCast(addr)), target_endian), | 2000 | .p32 => mem.writeInt(u32, buf.addManyAsArrayAssumeCapacity(4), @intCast(addr), target_endian), |
| 1914 | .p64 => mem.writeInt(u64, buf.addManyAsArrayAssumeCapacity(8), addr, target_endian), | 2001 | .p64 => mem.writeInt(u64, buf.addManyAsArrayAssumeCapacity(8), addr, target_endian), |
| 1915 | } | 2002 | } |
| 1916 | } | 2003 | } |
| ... | @@ -1918,12 +2005,7 @@ fn writeAddrAssumeCapacity(self: *Dwarf, buf: *std.ArrayList(u8), addr: u64) voi | ... | @@ -1918,12 +2005,7 @@ fn writeAddrAssumeCapacity(self: *Dwarf, buf: *std.ArrayList(u8), addr: u64) voi |
| 1918 | fn writeOffsetAssumeCapacity(self: *Dwarf, buf: *std.ArrayList(u8), off: u64) void { | 2005 | fn writeOffsetAssumeCapacity(self: *Dwarf, buf: *std.ArrayList(u8), off: u64) void { |
| 1919 | const target_endian = self.bin_file.options.target.cpu.arch.endian(); | 2006 | const target_endian = self.bin_file.options.target.cpu.arch.endian(); |
| 1920 | switch (self.format) { | 2007 | switch (self.format) { |
| 1921 | .dwarf32 => mem.writeInt( | 2008 | .dwarf32 => mem.writeInt(u32, buf.addManyAsArrayAssumeCapacity(4), @intCast(off), target_endian), |
| 1922 | u32, | | |
| 1923 | buf.addManyAsArrayAssumeCapacity(4), | | |
| 1924 | @as(u32, @intCast(off)), | | |
| 1925 | target_endian, | | |
| 1926 | ), | | |
| 1927 | .dwarf64 => mem.writeInt(u64, buf.addManyAsArrayAssumeCapacity(8), off, target_endian), | 2009 | .dwarf64 => mem.writeInt(u64, buf.addManyAsArrayAssumeCapacity(8), off, target_endian), |
| 1928 | } | 2010 | } |
| 1929 | } | 2011 | } |
| ... | @@ -2182,16 +2264,11 @@ pub fn writeDbgAranges(self: *Dwarf, addr: u64, size: u64) !void { | ... | @@ -2182,16 +2264,11 @@ pub fn writeDbgAranges(self: *Dwarf, addr: u64, size: u64) !void { |
| 2182 | // Go back and populate the initial length. | 2264 | // Go back and populate the initial length. |
| 2183 | const init_len = di_buf.items.len - after_init_len; | 2265 | const init_len = di_buf.items.len - after_init_len; |
| 2184 | switch (self.format) { | 2266 | switch (self.format) { |
| 2185 | .dwarf32 => mem.writeInt( | 2267 | .dwarf32 => mem.writeInt(u32, di_buf.items[init_len_index..][0..4], @intCast(init_len), target_endian), |
| 2186 | u32, | | |
| 2187 | di_buf.items[init_len_index..][0..4], | | |
| 2188 | @as(u32, @intCast(init_len)), | | |
| 2189 | target_endian, | | |
| 2190 | ), | | |
| 2191 | .dwarf64 => mem.writeInt(u64, di_buf.items[init_len_index..][0..8], init_len, target_endian), | 2268 | .dwarf64 => mem.writeInt(u64, di_buf.items[init_len_index..][0..8], init_len, target_endian), |
| 2192 | } | 2269 | } |
| 2193 | | 2270 | |
| 2194 | const needed_size = @as(u32, @intCast(di_buf.items.len)); | 2271 | const needed_size: u32 = @intCast(di_buf.items.len); |
| 2195 | switch (self.bin_file.tag) { | 2272 | switch (self.bin_file.tag) { |
| 2196 | .elf => { | 2273 | .elf => { |
| 2197 | const elf_file = self.bin_file.cast(File.Elf).?; | 2274 | const elf_file = self.bin_file.cast(File.Elf).?; |
| ... | @@ -2256,14 +2333,14 @@ pub fn writeDbgLineHeader(self: *Dwarf) !void { | ... | @@ -2256,14 +2333,14 @@ pub fn writeDbgLineHeader(self: *Dwarf) !void { |
| 2256 | self.writeOffsetAssumeCapacity(&di_buf, 0); // We will come back and write this. | 2333 | self.writeOffsetAssumeCapacity(&di_buf, 0); // We will come back and write this. |
| 2257 | const after_header_len = di_buf.items.len; | 2334 | const after_header_len = di_buf.items.len; |
| 2258 | | 2335 | |
| 2259 | const opcode_base = DW.LNS.set_isa + 1; | 2336 | assert(self.dbg_line_header.opcode_base == DW.LNS.set_isa + 1); |
| 2260 | di_buf.appendSliceAssumeCapacity(&[_]u8{ | 2337 | di_buf.appendSliceAssumeCapacity(&[_]u8{ |
| 2261 | 1, // minimum_instruction_length | 2338 | self.dbg_line_header.minimum_instruction_length, |
| 2262 | 1, // maximum_operations_per_instruction | 2339 | self.dbg_line_header.maximum_operations_per_instruction, |
| 2263 | 1, // default_is_stmt | 2340 | @intFromBool(self.dbg_line_header.default_is_stmt), |
| 2264 | 1, // line_base (signed) | 2341 | @bitCast(self.dbg_line_header.line_base), |
| 2265 | 1, // line_range | 2342 | self.dbg_line_header.line_range, |
| 2266 | opcode_base, | 2343 | self.dbg_line_header.opcode_base, |
| 2267 | | 2344 | |
| 2268 | // Standard opcode lengths. The number of items here is based on `opcode_base`. | 2345 | // Standard opcode lengths. The number of items here is based on `opcode_base`. |
| 2269 | // The value is the number of LEB128 operands the instruction takes. | 2346 | // The value is the number of LEB128 operands the instruction takes. |
| ... | @@ -2298,7 +2375,7 @@ pub fn writeDbgLineHeader(self: *Dwarf) !void { | ... | @@ -2298,7 +2375,7 @@ pub fn writeDbgLineHeader(self: *Dwarf) !void { |
| 2298 | di_buf.appendSliceAssumeCapacity(file); | 2375 | di_buf.appendSliceAssumeCapacity(file); |
| 2299 | di_buf.appendSliceAssumeCapacity(&[_]u8{ | 2376 | di_buf.appendSliceAssumeCapacity(&[_]u8{ |
| 2300 | 0, // null byte for the relative path name | 2377 | 0, // null byte for the relative path name |
| 2301 | @as(u8, @intCast(dir_index)), // directory_index | 2378 | @intCast(dir_index), // directory_index |
| 2302 | 0, // mtime (TODO supply this) | 2379 | 0, // mtime (TODO supply this) |
| 2303 | 0, // file size bytes (TODO supply this) | 2380 | 0, // file size bytes (TODO supply this) |
| 2304 | }); | 2381 | }); |
| ... | @@ -2307,12 +2384,7 @@ pub fn writeDbgLineHeader(self: *Dwarf) !void { | ... | @@ -2307,12 +2384,7 @@ pub fn writeDbgLineHeader(self: *Dwarf) !void { |
| 2307 | | 2384 | |
| 2308 | const header_len = di_buf.items.len - after_header_len; | 2385 | const header_len = di_buf.items.len - after_header_len; |
| 2309 | switch (self.format) { | 2386 | switch (self.format) { |
| 2310 | .dwarf32 => mem.writeInt( | 2387 | .dwarf32 => mem.writeInt(u32, di_buf.items[before_header_len..][0..4], @intCast(header_len), target_endian), |
| 2311 | u32, | | |
| 2312 | di_buf.items[before_header_len..][0..4], | | |
| 2313 | @as(u32, @intCast(header_len)), | | |
| 2314 | target_endian, | | |
| 2315 | ), | | |
| 2316 | .dwarf64 => mem.writeInt(u64, di_buf.items[before_header_len..][0..8], header_len, target_endian), | 2388 | .dwarf64 => mem.writeInt(u64, di_buf.items[before_header_len..][0..8], header_len, target_endian), |
| 2317 | } | 2389 | } |
| 2318 | | 2390 | |
| ... | @@ -2348,7 +2420,7 @@ pub fn writeDbgLineHeader(self: *Dwarf) !void { | ... | @@ -2348,7 +2420,7 @@ pub fn writeDbgLineHeader(self: *Dwarf) !void { |
| 2348 | .macho => { | 2420 | .macho => { |
| 2349 | const d_sym = self.bin_file.cast(File.MachO).?.getDebugSymbols().?; | 2421 | const d_sym = self.bin_file.cast(File.MachO).?.getDebugSymbols().?; |
| 2350 | const sect_index = d_sym.debug_line_section_index.?; | 2422 | const sect_index = d_sym.debug_line_section_index.?; |
| 2351 | const needed_size = @as(u32, @intCast(d_sym.getSection(sect_index).size + delta)); | 2423 | const needed_size: u32 = @intCast(d_sym.getSection(sect_index).size + delta); |
| 2352 | try d_sym.growSection(sect_index, needed_size, true); | 2424 | try d_sym.growSection(sect_index, needed_size, true); |
| 2353 | const file_pos = d_sym.getSection(sect_index).offset + first_fn.off; | 2425 | const file_pos = d_sym.getSection(sect_index).offset + first_fn.off; |
| 2354 | | 2426 | |
| ... | @@ -2384,7 +2456,7 @@ pub fn writeDbgLineHeader(self: *Dwarf) !void { | ... | @@ -2384,7 +2456,7 @@ pub fn writeDbgLineHeader(self: *Dwarf) !void { |
| 2384 | const init_len = self.getDebugLineProgramEnd().? - init_len_size; | 2456 | const init_len = self.getDebugLineProgramEnd().? - init_len_size; |
| 2385 | switch (self.format) { | 2457 | switch (self.format) { |
| 2386 | .dwarf32 => { | 2458 | .dwarf32 => { |
| 2387 | mem.writeInt(u32, di_buf.items[0..4], @as(u32, @intCast(init_len)), target_endian); | 2459 | mem.writeInt(u32, di_buf.items[0..4], @intCast(init_len), target_endian); |
| 2388 | }, | 2460 | }, |
| 2389 | .dwarf64 => { | 2461 | .dwarf64 => { |
| 2390 | mem.writeInt(u64, di_buf.items[4..][0..8], init_len, target_endian); | 2462 | mem.writeInt(u64, di_buf.items[4..][0..8], init_len, target_endian); |
| ... | @@ -2449,12 +2521,12 @@ fn ptrWidthBytes(self: Dwarf) u8 { | ... | @@ -2449,12 +2521,12 @@ fn ptrWidthBytes(self: Dwarf) u8 { |
| 2449 | | 2521 | |
| 2450 | fn dbgLineNeededHeaderBytes(self: Dwarf, dirs: []const []const u8, files: []const []const u8) u32 { | 2522 | fn dbgLineNeededHeaderBytes(self: Dwarf, dirs: []const []const u8, files: []const []const u8) u32 { |
| 2451 | var size: usize = switch (self.format) { // length field | 2523 | var size: usize = switch (self.format) { // length field |
| 2452 | .dwarf32 => @as(usize, 4), | 2524 | .dwarf32 => 4, |
| 2453 | .dwarf64 => 12, | 2525 | .dwarf64 => 12, |
| 2454 | }; | 2526 | }; |
| 2455 | size += @sizeOf(u16); // version field | 2527 | size += @sizeOf(u16); // version field |
| 2456 | size += switch (self.format) { // offset to end-of-header | 2528 | size += switch (self.format) { // offset to end-of-header |
| 2457 | .dwarf32 => @as(usize, 4), | 2529 | .dwarf32 => 4, |
| 2458 | .dwarf64 => 8, | 2530 | .dwarf64 => 8, |
| 2459 | }; | 2531 | }; |
| 2460 | size += 18; // opcodes | 2532 | size += 18; // opcodes |
| ... | @@ -2469,7 +2541,7 @@ fn dbgLineNeededHeaderBytes(self: Dwarf, dirs: []const []const u8, files: []cons | ... | @@ -2469,7 +2541,7 @@ fn dbgLineNeededHeaderBytes(self: Dwarf, dirs: []const []const u8, files: []cons |
| 2469 | } | 2541 | } |
| 2470 | size += 1; // file names sentinel | 2542 | size += 1; // file names sentinel |
| 2471 | | 2543 | |
| 2472 | return @as(u32, @intCast(size)); | 2544 | return @intCast(size); |
| 2473 | } | 2545 | } |
| 2474 | | 2546 | |
| 2475 | /// The reloc offset for the line offset of a function from the previous function's line. | 2547 | /// The reloc offset for the line offset of a function from the previous function's line. |
| ... | @@ -2514,22 +2586,20 @@ pub fn flushModule(self: *Dwarf, module: *Module) !void { | ... | @@ -2514,22 +2586,20 @@ pub fn flushModule(self: *Dwarf, module: *Module) !void { |
| 2514 | log.debug("writeDeclDebugInfo in flushModule", .{}); | 2586 | log.debug("writeDeclDebugInfo in flushModule", .{}); |
| 2515 | try self.writeDeclDebugInfo(di_atom_index, dbg_info_buffer.items); | 2587 | try self.writeDeclDebugInfo(di_atom_index, dbg_info_buffer.items); |
| 2516 | | 2588 | |
| 2517 | const file_pos = blk: { | 2589 | const file_pos = switch (self.bin_file.tag) { |
| 2518 | switch (self.bin_file.tag) { | 2590 | .elf => pos: { |
| 2519 | .elf => { | 2591 | const elf_file = self.bin_file.cast(File.Elf).?; |
| 2520 | const elf_file = self.bin_file.cast(File.Elf).?; | 2592 | const debug_info_sect = &elf_file.shdrs.items[elf_file.debug_info_section_index.?]; |
| 2521 | const debug_info_sect = &elf_file.shdrs.items[elf_file.debug_info_section_index.?]; | 2593 | break :pos debug_info_sect.sh_offset; |
| 2522 | break :blk debug_info_sect.sh_offset; | 2594 | }, |
| 2523 | }, | 2595 | .macho => pos: { |
| 2524 | .macho => { | 2596 | const d_sym = self.bin_file.cast(File.MachO).?.getDebugSymbols().?; |
| 2525 | const d_sym = self.bin_file.cast(File.MachO).?.getDebugSymbols().?; | 2597 | const debug_info_sect = d_sym.getSectionPtr(d_sym.debug_info_section_index.?); |
| 2526 | const debug_info_sect = d_sym.getSectionPtr(d_sym.debug_info_section_index.?); | 2598 | break :pos debug_info_sect.offset; |
| 2527 | break :blk debug_info_sect.offset; | 2599 | }, |
| 2528 | }, | 2600 | // for wasm, the offset is always 0 as we write to memory first |
| 2529 | // for wasm, the offset is always 0 as we write to memory first | 2601 | .wasm => 0, |
| 2530 | .wasm => break :blk @as(u32, 0), | 2602 | else => unreachable, |
| 2531 | else => unreachable, | | |
| 2532 | } | | |
| 2533 | }; | 2603 | }; |
| 2534 | | 2604 | |
| 2535 | var buf: [@sizeOf(u32)]u8 = undefined; | 2605 | var buf: [@sizeOf(u32)]u8 = undefined; |
| ... | @@ -2575,7 +2645,7 @@ fn addDIFile(self: *Dwarf, mod: *Module, decl_index: Module.Decl.Index) !u28 { | ... | @@ -2575,7 +2645,7 @@ fn addDIFile(self: *Dwarf, mod: *Module, decl_index: Module.Decl.Index) !u28 { |
| 2575 | else => unreachable, | 2645 | else => unreachable, |
| 2576 | } | 2646 | } |
| 2577 | } | 2647 | } |
| 2578 | return @as(u28, @intCast(gop.index + 1)); | 2648 | return @intCast(gop.index + 1); |
| 2579 | } | 2649 | } |
| 2580 | | 2650 | |
| 2581 | fn genIncludeDirsAndFileNames(self: *Dwarf, arena: Allocator) !struct { | 2651 | fn genIncludeDirsAndFileNames(self: *Dwarf, arena: Allocator) !struct { |
| ... | @@ -2603,9 +2673,9 @@ fn genIncludeDirsAndFileNames(self: *Dwarf, arena: Allocator) !struct { | ... | @@ -2603,9 +2673,9 @@ fn genIncludeDirsAndFileNames(self: *Dwarf, arena: Allocator) !struct { |
| 2603 | else | 2673 | else |
| 2604 | dir_path; | 2674 | dir_path; |
| 2605 | | 2675 | |
| 2606 | const dir_index: u28 = blk: { | 2676 | const dir_index: u28 = index: { |
| 2607 | const dirs_gop = dirs.getOrPutAssumeCapacity(try arena.dupe(u8, resolved)); | 2677 | const dirs_gop = dirs.getOrPutAssumeCapacity(try arena.dupe(u8, resolved)); |
| 2608 | break :blk @as(u28, @intCast(dirs_gop.index + 1)); | 2678 | break :index @intCast(dirs_gop.index + 1); |
| 2609 | }; | 2679 | }; |
| 2610 | | 2680 | |
| 2611 | files_dir_indexes.appendAssumeCapacity(dir_index); | 2681 | files_dir_indexes.appendAssumeCapacity(dir_index); |
| ... | @@ -2680,12 +2750,12 @@ fn createAtom(self: *Dwarf, comptime kind: Kind) !Atom.Index { | ... | @@ -2680,12 +2750,12 @@ fn createAtom(self: *Dwarf, comptime kind: Kind) !Atom.Index { |
| 2680 | const index = blk: { | 2750 | const index = blk: { |
| 2681 | switch (kind) { | 2751 | switch (kind) { |
| 2682 | .src_fn => { | 2752 | .src_fn => { |
| 2683 | const index = @as(Atom.Index, @intCast(self.src_fns.items.len)); | 2753 | const index: Atom.Index = @intCast(self.src_fns.items.len); |
| 2684 | _ = try self.src_fns.addOne(self.allocator); | 2754 | _ = try self.src_fns.addOne(self.allocator); |
| 2685 | break :blk index; | 2755 | break :blk index; |
| 2686 | }, | 2756 | }, |
| 2687 | .di_atom => { | 2757 | .di_atom => { |
| 2688 | const index = @as(Atom.Index, @intCast(self.di_atoms.items.len)); | 2758 | const index: Atom.Index = @intCast(self.di_atoms.items.len); |
| 2689 | _ = try self.di_atoms.addOne(self.allocator); | 2759 | _ = try self.di_atoms.addOne(self.allocator); |
| 2690 | break :blk index; | 2760 | break :blk index; |
| 2691 | }, | 2761 | }, |