@@ -37,12 +37,12 @@ if sys.version_info.major < 3:
3737Ehdr_size = 64
3838e_shnum_offset = 60
3939e_shoff_offset = 40
40-
40+ e_shstrndx_offset = 62
4141Shdr_size = 64
42+ sh_name_offset = 0
4243sh_type_offset = 4
4344sh_offset_offset = 24
4445sh_size_offset = 32
45- SHT_SYMTAB = 2
4646SHT_NOTE = 7
4747
4848Nhdr_size = 12
@@ -63,18 +63,32 @@ def handle_Nhdr(mv, sh_size):
6363 offset += Nhdr_size + align_up (n_namesz , 4 ) + align_up (n_descsz , 4 )
6464 return None
6565
66+ def handle_shstrtab (mv , e_shoff ):
67+ e_shstrndx , = struct .unpack_from ('<H' , buffer = mv , offset = e_shstrndx_offset )
68+
69+ start_shstrndx = e_shoff + e_shstrndx * Shdr_size
70+ shstrndx_sh = mv [start_shstrndx : start_shstrndx + Shdr_size ]
71+ _ , shstrndx_sh_offset , shstrndx_sh_size = handle_Shdr (shstrndx_sh )
72+ return mv [shstrndx_sh_offset :shstrndx_sh_offset + shstrndx_sh_size ]
73+
74+ def shstrtab_sh_name (mv ):
75+ name = ""
76+ for byte in mv :
77+ char = chr (byte )
78+ if char == '\x00 ' :
79+ break
80+ name += char
81+ return name
82+
6683def unpack_sh_type (mv ):
6784 sh_type , = struct .unpack_from ('<I' , buffer = mv , offset = sh_type_offset )
6885 return sh_type
6986
7087def handle_Shdr (mv ):
71- sh_type = unpack_sh_type (mv )
72- # Sanity check
73- if sh_type != SHT_NOTE :
74- return None , None
88+ name_offset , = struct .unpack_from ('<I' , buffer = mv , offset = sh_name_offset )
7589 sh_offset , = struct .unpack_from ('<Q' , buffer = mv , offset = sh_offset_offset )
7690 sh_size , = struct .unpack_from ('<Q' , buffer = mv , offset = sh_size_offset )
77- return sh_offset , sh_size
91+ return name_offset , sh_offset , sh_size
7892
7993def handle_elf (mv ):
8094 # \x02 is ELFCLASS64, \x01 is ELFDATA2LSB. HWASan currently only works on
@@ -86,23 +100,31 @@ def handle_elf(mv):
86100 bid = None
87101 e_shnum , = struct .unpack_from ('<H' , buffer = mv , offset = e_shnum_offset )
88102 e_shoff , = struct .unpack_from ('<Q' , buffer = mv , offset = e_shoff_offset )
103+
104+ # Section where all the section header names are stored
105+ shstr = handle_shstrtab (mv , e_shoff )
106+
89107 for i in range (0 , e_shnum ):
90108 start = e_shoff + i * Shdr_size
91109 sh = mv [start : start + Shdr_size ]
110+ sh_name_offset , sh_offset , sh_size = handle_Shdr (sh )
111+ sh_name = shstrtab_sh_name (shstr [sh_name_offset :])
92112 sh_type = unpack_sh_type (sh )
93113
94- if sh_type == SHT_SYMTAB :
114+ if sh_name == ".debug_info" :
95115 found_symbols = True
96- elif sh_type == SHT_NOTE :
97- sh_offset , sh_size = handle_Shdr (sh )
116+ if sh_type == SHT_NOTE :
98117 if sh_offset is None :
99118 continue
100119 note_hdr = mv [sh_offset : sh_offset + sh_size ]
101120 result = handle_Nhdr (note_hdr , sh_size )
102121 if result is not None :
103122 bid = result
104123
105- return (found_symbols , bid )
124+ if found_symbols :
125+ return bid
126+ else :
127+ return None
106128
107129def read_elf (filename ):
108130 with open (filename , "r" ) as fd :
@@ -284,13 +306,13 @@ class Symbolizer:
284306 for fn in fnames :
285307 filename = os .path .join (dname , fn )
286308 try :
287- found_symbols , bid = read_elf (filename )
309+ bid = read_elf (filename )
288310 except FileNotFoundError :
289311 continue
290312 except Exception as e :
291313 print ("Failed to parse {}: {}" .format (filename , e ), file = sys .stderr )
292314 continue
293- if found_symbols and bid is not None :
315+ if bid is not None :
294316 if bid in self .__index :
295317 print ("Duplicate build ID {} for {} and {}" .format (bid , self .__index [bid ], filename ), file = sys .stderr )
296318 sys .exit (1 )
0 commit comments