@@ -185,12 +185,17 @@ const ElfStackTrace = struct {
185
185
}
186
186
};
187
187
188
+ const PcRange = struct {
189
+ start : u64 ,
190
+ end : u64 ,
191
+ };
192
+
188
193
const CompileUnit = struct {
194
+ version : u16 ,
189
195
is_64 : bool ,
190
196
die : & Die ,
191
- pc_start : u64 ,
192
- pc_end : u64 ,
193
197
index : usize ,
198
+ pc_range : ? PcRange ,
194
199
};
195
200
196
201
const AbbrevTable = List (AbbrevTableEntry );
@@ -259,23 +264,23 @@ const Die = struct {
259
264
}
260
265
261
266
fn getAttrAddr (self : & const Die , id : u64 ) - > % u64 {
262
- const form_value = self .getAttr (id ) ?? return error .InvalidDebugInfo ;
267
+ const form_value = self .getAttr (id ) ?? return error .MissingDebugInfo ;
263
268
return switch (* form_value ) {
264
269
FormValue .Address = > | value | value ,
265
270
else = > error .InvalidDebugInfo ,
266
271
};
267
272
}
268
273
269
274
fn getAttrUnsignedLe (self : & const Die , id : u64 ) - > % u64 {
270
- const form_value = self .getAttr (id ) ?? return error .InvalidDebugInfo ;
275
+ const form_value = self .getAttr (id ) ?? return error .MissingDebugInfo ;
271
276
return switch (* form_value ) {
272
277
FormValue .Const = > | value | value .asUnsignedLe (),
273
278
else = > error .InvalidDebugInfo ,
274
279
};
275
280
}
276
281
277
282
fn getAttrString (self : & const Die , st : & ElfStackTrace , id : u64 ) - > % []u8 {
278
- const form_value = self .getAttr (id ) ?? return error .InvalidDebugInfo ;
283
+ const form_value = self .getAttr (id ) ?? return error .MissingDebugInfo ;
279
284
return switch (* form_value ) {
280
285
FormValue .String = > | value | value ,
281
286
FormValue .StrPtr = > | offset | getString (st , offset ),
@@ -794,7 +799,7 @@ fn scanAllCompileUnits(st: &ElfStackTrace) -> %void {
794
799
const next_offset = unit_length + (if (is_64 ) usize (12 ) else usize (4 ));
795
800
796
801
const version = % return st .self_exe_stream .readInt (st .elf .is_big_endian , u16 );
797
- if (version != 4 ) return error .InvalidDebugInfo ;
802
+ if (version < 2 or version > 5 ) return error .InvalidDebugInfo ;
798
803
799
804
const debug_abbrev_offset = if (is_64 ) {
800
805
% return st .self_exe_stream .readInt (st .elf .is_big_endian , u64 )
@@ -815,22 +820,36 @@ fn scanAllCompileUnits(st: &ElfStackTrace) -> %void {
815
820
816
821
if (compile_unit_die .tag_id != DW .TAG_compile_unit )
817
822
return error .InvalidDebugInfo ;
818
- const low_pc = % return compile_unit_die .getAttrAddr (DW .AT_low_pc );
819
823
820
- const high_pc_value = compile_unit_die .getAttr (DW .AT_high_pc ) ?? return error .MissingDebugInfo ;
821
- const pc_end = switch (* high_pc_value ) {
822
- FormValue .Address = > | value | value ,
823
- FormValue .Const = > | value | {
824
- const offset = % return value .asUnsignedLe ();
825
- low_pc + offset
826
- },
827
- else = > return error .InvalidDebugInfo ,
824
+ const pc_range = {
825
+ try (compile_unit_die .getAttrAddr (DW .AT_low_pc )) | low_pc | {
826
+ test (compile_unit_die .getAttr (DW .AT_high_pc )) | high_pc_value | {
827
+ const pc_end = switch (* high_pc_value ) {
828
+ FormValue .Address = > | value | value ,
829
+ FormValue .Const = > | value | {
830
+ const offset = % return value .asUnsignedLe ();
831
+ low_pc + offset
832
+ },
833
+ else = > return error .InvalidDebugInfo ,
834
+ };
835
+ PcRange {
836
+ .start = low_pc ,
837
+ .end = pc_end ,
838
+ }
839
+ } else {
840
+ null
841
+ }
842
+ } else | err | {
843
+ if (err != error .MissingDebugInfo )
844
+ return err ;
845
+ null
846
+ }
828
847
};
829
848
830
849
% return st .compile_unit_list .append (CompileUnit {
850
+ .version = version ,
831
851
.is_64 = is_64 ,
832
- .pc_start = low_pc ,
833
- .pc_end = pc_end ,
852
+ .pc_range = pc_range ,
834
853
.die = compile_unit_die ,
835
854
.index = cu_index ,
836
855
});
@@ -842,8 +861,10 @@ fn scanAllCompileUnits(st: &ElfStackTrace) -> %void {
842
861
843
862
fn findCompileUnit (st : & ElfStackTrace , target_address : u64 ) - > ? & const CompileUnit {
844
863
for (st .compile_unit_list .toSlice ()) | * compile_unit | {
845
- if (target_address >= compile_unit .pc_start and target_address < compile_unit .pc_end )
846
- return compile_unit ;
864
+ test (compile_unit .pc_range ) | range | {
865
+ if (target_address >= range .start and target_address < range .end )
866
+ return compile_unit ;
867
+ }
847
868
}
848
869
return null ;
849
870
}
0 commit comments