15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import bisect 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import re 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)_ARGUMENT_TYPE_PATTERN = re.compile('\([^()]*\)(\s*const)?') 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)_TEMPLATE_ARGUMENT_PATTERN = re.compile('<[^<>]*>') 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)_LEADING_TYPE_PATTERN = re.compile('^.*\s+(\w+::)') 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)_READELF_SECTION_HEADER_PATTER = re.compile( 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) '^\s*\[\s*(Nr|\d+)\]\s+(|\S+)\s+([A-Z_]+)\s+([0-9a-f]+)\s+' 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) '([0-9a-f]+)\s+([0-9a-f]+)\s+([0-9]+)\s+([WAXMSILGxOop]*)\s+' 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) '([0-9]+)\s+([0-9]+)\s+([0-9]+)') 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ParsingException(Exception): 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def __str__(self): 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return repr(self.args[0]) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class AddressMapping(object): 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def __init__(self): 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self._symbol_map = {} 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def append(self, start, entry): 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self._symbol_map[start] = entry 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def find(self, address): 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return self._symbol_map.get(address) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class RangeAddressMapping(AddressMapping): 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def __init__(self): 36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) super(RangeAddressMapping, self).__init__() 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self._sorted_start_list = [] 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self._is_sorted = True 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def append(self, start, entry): 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if self._sorted_start_list: 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if self._sorted_start_list[-1] > start: 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self._is_sorted = False 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) elif self._sorted_start_list[-1] == start: 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self._sorted_start_list.append(start) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self._symbol_map[start] = entry 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def find(self, address): 50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if not self._sorted_start_list: 51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return None 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if not self._is_sorted: 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self._sorted_start_list.sort() 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self._is_sorted = True 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) found_index = bisect.bisect_left(self._sorted_start_list, address) 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) found_start_address = self._sorted_start_list[found_index - 1] 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return self._symbol_map[found_start_address] 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Procedure(object): 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """A class for a procedure symbol and an address range for the symbol.""" 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def __init__(self, start, end, name): 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.start = start 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.end = end 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.name = name 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def __eq__(self, other): 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (self.start == other.start and 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.end == other.end and 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.name == other.name) 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def __ne__(self, other): 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return not self.__eq__(other) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def __str__(self): 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return '%x-%x: %s' % (self.start, self.end, self.name) 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ElfSection(object): 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """A class for an elf section header.""" 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def __init__( 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self, number, name, stype, address, offset, size, es, flg, lk, inf, al): 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.number = number 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.name = name 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.stype = stype 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.address = address 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.offset = offset 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.size = size 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.es = es 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.flg = flg 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.lk = lk 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.inf = inf 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.al = al 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def __eq__(self, other): 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (self.number == other.number and 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.name == other.name and 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.stype == other.stype and 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.address == other.address and 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.offset == other.offset and 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.size == other.size and 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.es == other.es and 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.flg == other.flg and 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.lk == other.lk and 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.inf == other.inf and 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.al == other.al) 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def __ne__(self, other): 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return not self.__eq__(other) 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def __str__(self): 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return '%x+%x(%x) %s' % (self.address, self.size, self.offset, self.name) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class StaticSymbolsInFile(object): 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Represents static symbol information in a binary file.""" 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def __init__(self, my_name): 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.my_name = my_name 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self._elf_sections = [] 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self._procedures = RangeAddressMapping() 124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) self._sourcefiles = RangeAddressMapping() 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self._typeinfos = AddressMapping() 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def _append_elf_section(self, elf_section): 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self._elf_sections.append(elf_section) 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def _append_procedure(self, start, procedure): 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self._procedures.append(start, procedure) 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) def _append_sourcefile(self, start, sourcefile): 134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) self._sourcefiles.append(start, sourcefile) 135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def _append_typeinfo(self, start, typeinfo): 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self._typeinfos.append(start, typeinfo) 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def _find_symbol_by_runtime_address(self, address, vma, target): 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if not (vma.begin <= address < vma.end): 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return None 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if vma.name != self.my_name: 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return None 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_offset = address - (vma.begin - vma.offset) 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) elf_address = None 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for section in self._elf_sections: 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if section.offset <= file_offset < (section.offset + section.size): 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) elf_address = section.address + file_offset - section.offset 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if not elf_address: 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return None 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return target.find(elf_address) 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def find_procedure_by_runtime_address(self, address, vma): 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return self._find_symbol_by_runtime_address(address, vma, self._procedures) 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) def find_sourcefile_by_runtime_address(self, address, vma): 160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return self._find_symbol_by_runtime_address(address, vma, self._sourcefiles) 161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def find_typeinfo_by_runtime_address(self, address, vma): 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return self._find_symbol_by_runtime_address(address, vma, self._typeinfos) 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def load_readelf_ew(self, f): 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) found_header = False 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for line in f: 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if line.rstrip() == 'Section Headers:': 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) found_header = True 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if not found_header: 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return None 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for line in f: 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) line = line.rstrip() 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) matched = _READELF_SECTION_HEADER_PATTER.match(line) 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if matched: 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self._append_elf_section(ElfSection( 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int(matched.group(1), 10), # number 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) matched.group(2), # name 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) matched.group(3), # stype 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int(matched.group(4), 16), # address 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int(matched.group(5), 16), # offset 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int(matched.group(6), 16), # size 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) matched.group(7), # es 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) matched.group(8), # flg 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) matched.group(9), # lk 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) matched.group(10), # inf 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) matched.group(11) # al 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) )) 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if line in ('Key to Flags:', 'Program Headers:'): 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) def load_readelf_debug_decodedline_file(self, input_file): 196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for line in input_file: 197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) splitted = line.rstrip().split(None, 2) 198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) self._append_sourcefile(int(splitted[0], 16), splitted[1]) 199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) @staticmethod 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def _parse_nm_bsd_line(line): 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if line[8] == ' ': 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return line[0:8], line[9], line[11:] 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) elif line[16] == ' ': 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return line[0:16], line[17], line[19:] 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) raise ParsingException('Invalid nm output.') 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) @staticmethod 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def _get_short_function_name(function): 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while True: 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) function, number = _ARGUMENT_TYPE_PATTERN.subn('', function) 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if not number: 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while True: 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) function, number = _TEMPLATE_ARGUMENT_PATTERN.subn('', function) 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if not number: 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return _LEADING_TYPE_PATTERN.sub('\g<1>', function) 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def load_nm_bsd(self, f, mangled=False): 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_start = 0 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) routine = '' 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for line in f: 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) line = line.rstrip() 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sym_value, sym_type, sym_name = self._parse_nm_bsd_line(line) 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if sym_value[0] == ' ': 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) start_val = int(sym_value, 16) 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sym_type in ('r', 'R', 'D', 'U', 'd', 'V') and 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (not mangled and sym_name.startswith('typeinfo'))): 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self._append_typeinfo(start_val, sym_name) 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # It's possible for two symbols to share the same address, if 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # one is a zero-length variable (like __start_google_malloc) or 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # one symbol is a weak alias to another (like __libc_malloc). 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # In such cases, we want to ignore all values except for the 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # actual symbol, which in nm-speak has type "T". The logic 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # below does this, though it's a bit tricky: what happens when 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # we have a series of lines with the same address, is the first 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # one gets queued up to be processed. However, it won't 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # *actually* be processed until later, when we read a line with 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # a different address. That means that as long as we're reading 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # lines with the same address, we have a chance to replace that 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # item in the queue, which we do whenever we see a 'T' entry -- 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # that is, a line with type 'T'. If we never see a 'T' entry, 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # we'll just go ahead and process the first entry (which never 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # got touched in the queue), and ignore the others. 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if start_val == last_start and (sym_type == 't' or sym_type == 'T'): 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # We are the 'T' symbol at this address, replace previous symbol. 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) routine = sym_name 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) elif start_val == last_start: 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # We're not the 'T' symbol at this address, so ignore us. 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Tag this routine with the starting address in case the image 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # has multiple occurrences of this routine. We use a syntax 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # that resembles template paramters that are automatically 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # stripped out by ShortFunctionName() 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sym_name += "<%016x>" % start_val 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if not mangled: 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) routine = self._get_short_function_name(routine) 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self._append_procedure( 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_start, Procedure(last_start, start_val, routine)) 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_start = start_val 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) routine = sym_name 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if not mangled: 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) routine = self._get_short_function_name(routine) 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self._append_procedure( 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_start, Procedure(last_start, last_start, routine)) 278