22
22
from absl import logging
23
23
from elftools .elf import elffile
24
24
25
+ _IGNORED_UNIT_TYPES = ("DW_UT_type" , "DW_UT_split_type" )
26
+
27
+ # yapf: disable
28
+
25
29
26
30
@dataclasses .dataclass
27
31
class CompilationUnit :
@@ -45,7 +49,8 @@ class CompilationUnit:
45
49
46
50
47
51
def get_all_compilation_units (
48
- elf_file_path : os .PathLike [str ],) -> list [CompilationUnit ]:
52
+ elf_file_path : os .PathLike [str ],
53
+ ) -> list [CompilationUnit ]:
49
54
"""Parses compilation units from an ELF file.
50
55
51
56
Args:
@@ -62,20 +67,33 @@ def get_all_compilation_units(
62
67
return []
63
68
dwarf_info = elf_file .get_dwarf_info ()
64
69
for compilation_unit in dwarf_info .iter_CUs ():
65
- # Only compile and partial unit headers will be followed by a
66
- # DW_TAG_compile_unit or DW_TAG_partial entry with the expected
67
- # attributes.
68
- if compilation_unit .header .unit_type not in (
70
+ if compilation_unit .header .version < 5 :
71
+ # Only DWARF5 has a unit_type field in the header.
72
+ # For older versions, we do a best effort approach.
73
+ logging .warning (
74
+ "[!] Compilation Unit with unsupported DWARF version %d" ,
75
+ compilation_unit .header .version ,
76
+ )
77
+ elif compilation_unit .header .unit_type in _IGNORED_UNIT_TYPES :
78
+ # Type units are not interesting for us.
79
+ continue
80
+ elif compilation_unit .header .unit_type not in (
69
81
"DW_UT_compile" ,
70
82
"DW_UT_partial" ,
71
83
):
72
- continue
84
+ raise ValueError (
85
+ "Unsupported DWARF compilation unit type"
86
+ f" { compilation_unit .header .unit_type } "
87
+ )
73
88
74
89
top_debug_info_entry = compilation_unit .get_top_DIE ()
75
90
if top_debug_info_entry .tag != "DW_TAG_compile_unit" :
76
91
logging .error ("Top DIE is not a full compile unit" )
77
- producer = top_debug_info_entry .attributes ["DW_AT_producer" ].value .decode (
78
- )
92
+
93
+ producer = top_debug_info_entry .attributes [
94
+ "DW_AT_producer"
95
+ ].value .decode ()
96
+
79
97
name = top_debug_info_entry .attributes ["DW_AT_name" ].value .decode ()
80
98
language = top_debug_info_entry .attributes ["DW_AT_language" ].value
81
99
compdir = top_debug_info_entry .attributes ["DW_AT_comp_dir" ].value .decode ()
@@ -85,12 +103,14 @@ def get_all_compilation_units(
85
103
apple_flags = None
86
104
if top_debug_info_entry .attributes .get ("DW_AT_APPLE_flags" , None ):
87
105
apple_flags = top_debug_info_entry .attributes [
88
- "DW_AT_APPLE_flags" ].value .decode ()
106
+ "DW_AT_APPLE_flags"
107
+ ].value .decode ()
89
108
90
109
isysroot = None
91
110
if top_debug_info_entry .attributes .get ("DW_AT_LLVM_isysroot" , None ):
92
111
isysroot = top_debug_info_entry .attributes [
93
- "DW_AT_LLVM_isysroot" ].value .decode ()
112
+ "DW_AT_LLVM_isysroot"
113
+ ].value .decode ()
94
114
95
115
result .append (
96
116
CompilationUnit (
@@ -100,7 +120,8 @@ def get_all_compilation_units(
100
120
language = language ,
101
121
apple_flags = apple_flags ,
102
122
isysroot = isysroot ,
103
- ))
123
+ )
124
+ )
104
125
return result
105
126
106
127
0 commit comments