| ... | @@ -114,12 +114,14 @@ pub const Abbrev = struct { | ... | @@ -114,12 +114,14 @@ pub const Abbrev = struct { |
| 114 | }; | 114 | }; |
| 115 | | 115 | |
| 116 | pub const CompileUnit = struct { | 116 | pub const CompileUnit = struct { |
| | 117 | offset: u64, |
| | 118 | size: u64, |
| 117 | version: u16, | 119 | version: u16, |
| 118 | format: Format, | 120 | format: Format, |
| 119 | addr_size_bytes: u8, | 121 | addr_size_bytes: u8, |
| | 122 | abbrev_offset: u64, |
| 120 | die: Die, | 123 | die: Die, |
| 121 | pc_range: ?PcRange, | 124 | pc_range: ?PcRange, |
| 122 | | | |
| 123 | str_offsets_base: usize, | 125 | str_offsets_base: usize, |
| 124 | addr_base: usize, | 126 | addr_base: usize, |
| 125 | rnglists_base: usize, | 127 | rnglists_base: usize, |
| ... | @@ -246,14 +248,6 @@ pub const Die = struct { | ... | @@ -246,14 +248,6 @@ pub const Die = struct { |
| 246 | return form_value.getUInt(u64); | 248 | return form_value.getUInt(u64); |
| 247 | } | 249 | } |
| 248 | | 250 | |
| 249 | fn getAttrUnsignedLe(self: *const Die, id: u64) !u64 { | | |
| 250 | const form_value = self.getAttr(id) orelse return error.MissingDebugInfo; | | |
| 251 | return switch (form_value.*) { | | |
| 252 | .Const => |value| value.asUnsignedLe(), | | |
| 253 | else => bad(), | | |
| 254 | }; | | |
| 255 | } | | |
| 256 | | | |
| 257 | fn getAttrRef(self: *const Die, id: u64, unit_offset: u64, unit_len: u64) !u64 { | 251 | fn getAttrRef(self: *const Die, id: u64, unit_offset: u64, unit_len: u64) !u64 { |
| 258 | const form_value = self.getAttr(id) orelse return error.MissingDebugInfo; | 252 | const form_value = self.getAttr(id) orelse return error.MissingDebugInfo; |
| 259 | return switch (form_value.*) { | 253 | return switch (form_value.*) { |
| ... | @@ -425,12 +419,14 @@ fn scanAllFunctions(di: *Dwarf, gpa: Allocator, endian: Endian) ScanError!void { | ... | @@ -425,12 +419,14 @@ fn scanAllFunctions(di: *Dwarf, gpa: Allocator, endian: Endian) ScanError!void { |
| 425 | const next_unit_pos = this_unit_offset + next_offset; | 419 | const next_unit_pos = this_unit_offset + next_offset; |
| 426 | | 420 | |
| 427 | var compile_unit: CompileUnit = .{ | 421 | var compile_unit: CompileUnit = .{ |
| | 422 | .offset = this_unit_offset, |
| | 423 | .size = next_offset, |
| 428 | .version = version, | 424 | .version = version, |
| 429 | .format = unit_header.format, | 425 | .format = unit_header.format, |
| 430 | .addr_size_bytes = address_size, | 426 | .addr_size_bytes = address_size, |
| | 427 | .abbrev_offset = debug_abbrev_offset, |
| 431 | .die = undefined, | 428 | .die = undefined, |
| 432 | .pc_range = null, | 429 | .pc_range = null, |
| 433 | | | |
| 434 | .str_offsets_base = 0, | 430 | .str_offsets_base = 0, |
| 435 | .addr_base = 0, | 431 | .addr_base = 0, |
| 436 | .rnglists_base = 0, | 432 | .rnglists_base = 0, |
| ... | @@ -624,9 +620,12 @@ fn scanAllCompileUnits(di: *Dwarf, gpa: Allocator, endian: Endian) ScanError!voi | ... | @@ -624,9 +620,12 @@ fn scanAllCompileUnits(di: *Dwarf, gpa: Allocator, endian: Endian) ScanError!voi |
| 624 | compile_unit_die.attrs = try gpa.dupe(Die.Attr, compile_unit_die.attrs); | 620 | compile_unit_die.attrs = try gpa.dupe(Die.Attr, compile_unit_die.attrs); |
| 625 | | 621 | |
| 626 | var compile_unit: CompileUnit = .{ | 622 | var compile_unit: CompileUnit = .{ |
| | 623 | .offset = this_unit_offset, |
| | 624 | .size = next_offset, |
| 627 | .version = version, | 625 | .version = version, |
| 628 | .format = unit_header.format, | 626 | .format = unit_header.format, |
| 629 | .addr_size_bytes = address_size, | 627 | .addr_size_bytes = address_size, |
| | 628 | .abbrev_offset = debug_abbrev_offset, |
| 630 | .pc_range = null, | 629 | .pc_range = null, |
| 631 | .die = compile_unit_die, | 630 | .die = compile_unit_die, |
| 632 | .str_offsets_base = if (compile_unit_die.getAttr(AT.str_offsets_base)) |fv| try fv.getUInt(usize) else 0, | 631 | .str_offsets_base = if (compile_unit_die.getAttr(AT.str_offsets_base)) |fv| try fv.getUInt(usize) else 0, |
| ... | @@ -1097,6 +1096,16 @@ fn runLineNumberProgram(d: *Dwarf, gpa: Allocator, endian: Endian, compile_unit: | ... | @@ -1097,6 +1096,16 @@ fn runLineNumberProgram(d: *Dwarf, gpa: Allocator, endian: Endian, compile_unit: |
| 1097 | } | 1096 | } |
| 1098 | } | 1097 | } |
| 1099 | | 1098 | |
| | 1099 | const abbrev_table = try d.getAbbrevTable(gpa, compile_unit.abbrev_offset); |
| | 1100 | const attrs_buf = try gpa.alloc(Die.Attr, max_attrs: { |
| | 1101 | var max_attrs: usize = 0; |
| | 1102 | for (abbrev_table.abbrevs) |abbrev| { |
| | 1103 | max_attrs = @max(max_attrs, abbrev.attrs.len); |
| | 1104 | } |
| | 1105 | break :max_attrs max_attrs; |
| | 1106 | }); |
| | 1107 | defer gpa.free(attrs_buf); |
| | 1108 | |
| 1100 | var prog = LineNumberProgram.init(default_is_stmt, version); | 1109 | var prog = LineNumberProgram.init(default_is_stmt, version); |
| 1101 | var line_table: CompileUnit.SrcLocCache.LineTable = .{}; | 1110 | var line_table: CompileUnit.SrcLocCache.LineTable = .{}; |
| 1102 | errdefer line_table.deinit(gpa); | 1111 | errdefer line_table.deinit(gpa); |
| ... | @@ -1144,6 +1153,64 @@ fn runLineNumberProgram(d: *Dwarf, gpa: Allocator, endian: Endian, compile_unit: | ... | @@ -1144,6 +1153,64 @@ fn runLineNumberProgram(d: *Dwarf, gpa: Allocator, endian: Endian, compile_unit: |
| 1144 | .size = size, | 1153 | .size = size, |
| 1145 | }); | 1154 | }); |
| 1146 | }, | 1155 | }, |
| | 1156 | DW.LNE.ZIG_set_decl => { |
| | 1157 | const decl_die_offset = try readFormatSizedInt(&fr, unit_header.format, endian); |
| | 1158 | var di_fr: Reader = .fixed(d.section(.debug_info) orelse continue); |
| | 1159 | di_fr.seek = @intCast(decl_die_offset); |
| | 1160 | var die = (try parseDie( |
| | 1161 | &di_fr, |
| | 1162 | attrs_buf, |
| | 1163 | abbrev_table, |
| | 1164 | unit_header.format, |
| | 1165 | endian, |
| | 1166 | addr_size_bytes, |
| | 1167 | compile_unit.version, |
| | 1168 | )) orelse continue; |
| | 1169 | if (die.getAttr(AT.low_pc)) |_| { |
| | 1170 | prog.address = try die.getAttrAddr(d, endian, AT.low_pc, compile_unit); |
| | 1171 | } |
| | 1172 | if (die.getAttr(AT.decl_line)) |decl_line| { |
| | 1173 | prog.line = try decl_line.getUInt(i64); |
| | 1174 | } |
| | 1175 | if (die.getAttr(AT.decl_column)) |decl_column| { |
| | 1176 | prog.column = try decl_column.getUInt(u64); |
| | 1177 | } |
| | 1178 | while (die.getAttr(AT.decl_file) == null) { |
| | 1179 | if (die.getAttr(AT.abstract_origin)) |_| { |
| | 1180 | di_fr.seek = @intCast(try die.getAttrRef( |
| | 1181 | AT.abstract_origin, |
| | 1182 | compile_unit.offset, |
| | 1183 | compile_unit.size, |
| | 1184 | )); |
| | 1185 | } else if (die.getAttr(AT.specification)) |_| { |
| | 1186 | di_fr.seek = @intCast(try die.getAttrRef( |
| | 1187 | AT.specification, |
| | 1188 | compile_unit.offset, |
| | 1189 | compile_unit.size, |
| | 1190 | )); |
| | 1191 | } else if (die.getAttr(AT.ZIG_parent)) |_| { |
| | 1192 | di_fr.seek = @intCast(try die.getAttrRef( |
| | 1193 | AT.ZIG_parent, |
| | 1194 | compile_unit.offset, |
| | 1195 | compile_unit.size, |
| | 1196 | )); |
| | 1197 | } else { |
| | 1198 | // no parent, so we can't find DW_AT_decl_file |
| | 1199 | break; |
| | 1200 | } |
| | 1201 | die = (try parseDie( |
| | 1202 | &di_fr, |
| | 1203 | attrs_buf, |
| | 1204 | abbrev_table, |
| | 1205 | unit_header.format, |
| | 1206 | endian, |
| | 1207 | addr_size_bytes, |
| | 1208 | compile_unit.version, |
| | 1209 | )) orelse break; |
| | 1210 | } else { |
| | 1211 | prog.file = try die.getAttr(AT.decl_file).?.getUInt(usize); |
| | 1212 | } |
| | 1213 | }, |
| 1147 | else => try fr.discardAll64(op_size - 1), | 1214 | else => try fr.discardAll64(op_size - 1), |
| 1148 | } | 1215 | } |
| 1149 | } else if (opcode >= opcode_base) { | 1216 | } else if (opcode >= opcode_base) { |