| ... | ... | @@ -114,12 +114,14 @@ pub const Abbrev = struct { |
| 114 | 114 | }; |
| 115 | 115 | |
| 116 | 116 | pub const CompileUnit = struct { |
| 117 | offset: u64, |
| 118 | size: u64, |
| 117 | 119 | version: u16, |
| 118 | 120 | format: Format, |
| 119 | 121 | addr_size_bytes: u8, |
| 122 | abbrev_offset: u64, |
| 120 | 123 | die: Die, |
| 121 | 124 | pc_range: ?PcRange, |
| 122 | | |
| 123 | 125 | str_offsets_base: usize, |
| 124 | 126 | addr_base: usize, |
| 125 | 127 | rnglists_base: usize, |
| ... | ... | @@ -246,14 +248,6 @@ pub const Die = struct { |
| 246 | 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 | 251 | fn getAttrRef(self: *const Die, id: u64, unit_offset: u64, unit_len: u64) !u64 { |
| 258 | 252 | const form_value = self.getAttr(id) orelse return error.MissingDebugInfo; |
| 259 | 253 | return switch (form_value.*) { |
| ... | ... | @@ -425,12 +419,14 @@ fn scanAllFunctions(di: *Dwarf, gpa: Allocator, endian: Endian) ScanError!void { |
| 425 | 419 | const next_unit_pos = this_unit_offset + next_offset; |
| 426 | 420 | |
| 427 | 421 | var compile_unit: CompileUnit = .{ |
| 422 | .offset = this_unit_offset, |
| 423 | .size = next_offset, |
| 428 | 424 | .version = version, |
| 429 | 425 | .format = unit_header.format, |
| 430 | 426 | .addr_size_bytes = address_size, |
| 427 | .abbrev_offset = debug_abbrev_offset, |
| 431 | 428 | .die = undefined, |
| 432 | 429 | .pc_range = null, |
| 433 | | |
| 434 | 430 | .str_offsets_base = 0, |
| 435 | 431 | .addr_base = 0, |
| 436 | 432 | .rnglists_base = 0, |
| ... | ... | @@ -624,9 +620,12 @@ fn scanAllCompileUnits(di: *Dwarf, gpa: Allocator, endian: Endian) ScanError!voi |
| 624 | 620 | compile_unit_die.attrs = try gpa.dupe(Die.Attr, compile_unit_die.attrs); |
| 625 | 621 | |
| 626 | 622 | var compile_unit: CompileUnit = .{ |
| 623 | .offset = this_unit_offset, |
| 624 | .size = next_offset, |
| 627 | 625 | .version = version, |
| 628 | 626 | .format = unit_header.format, |
| 629 | 627 | .addr_size_bytes = address_size, |
| 628 | .abbrev_offset = debug_abbrev_offset, |
| 630 | 629 | .pc_range = null, |
| 631 | 630 | .die = compile_unit_die, |
| 632 | 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 | 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 | 1109 | var prog = LineNumberProgram.init(default_is_stmt, version); |
| 1101 | 1110 | var line_table: CompileUnit.SrcLocCache.LineTable = .{}; |
| 1102 | 1111 | errdefer line_table.deinit(gpa); |
| ... | ... | @@ -1144,6 +1153,64 @@ fn runLineNumberProgram(d: *Dwarf, gpa: Allocator, endian: Endian, compile_unit: |
| 1144 | 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 | 1214 | else => try fr.discardAll64(op_size - 1), |
| 1148 | 1215 | } |
| 1149 | 1216 | } else if (opcode >= opcode_base) { |