OLD | NEW |
1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
4 | 4 |
5 import bisect | 5 import bisect |
6 import re | 6 import re |
7 | 7 |
8 | 8 |
9 _ARGUMENT_TYPE_PATTERN = re.compile('\([^()]*\)(\s*const)?') | 9 _ARGUMENT_TYPE_PATTERN = re.compile('\([^()]*\)(\s*const)?') |
10 _TEMPLATE_ARGUMENT_PATTERN = re.compile('<[^<>]*>') | 10 _TEMPLATE_ARGUMENT_PATTERN = re.compile('<[^<>]*>') |
(...skipping 15 matching lines...) Expand all Loading... |
26 | 26 |
27 def append(self, start, entry): | 27 def append(self, start, entry): |
28 self._symbol_map[start] = entry | 28 self._symbol_map[start] = entry |
29 | 29 |
30 def find(self, address): | 30 def find(self, address): |
31 return self._symbol_map.get(address) | 31 return self._symbol_map.get(address) |
32 | 32 |
33 | 33 |
34 class RangeAddressMapping(AddressMapping): | 34 class RangeAddressMapping(AddressMapping): |
35 def __init__(self): | 35 def __init__(self): |
36 AddressMapping.__init__(self) | 36 super(RangeAddressMapping, self).__init__() |
37 self._sorted_start_list = [] | 37 self._sorted_start_list = [] |
38 self._is_sorted = True | 38 self._is_sorted = True |
39 | 39 |
40 def append(self, start, entry): | 40 def append(self, start, entry): |
41 if self._sorted_start_list: | 41 if self._sorted_start_list: |
42 if self._sorted_start_list[-1] > start: | 42 if self._sorted_start_list[-1] > start: |
43 self._is_sorted = False | 43 self._is_sorted = False |
44 elif self._sorted_start_list[-1] == start: | 44 elif self._sorted_start_list[-1] == start: |
45 return | 45 return |
46 self._sorted_start_list.append(start) | 46 self._sorted_start_list.append(start) |
47 self._symbol_map[start] = entry | 47 self._symbol_map[start] = entry |
48 | 48 |
49 def find(self, address): | 49 def find(self, address): |
| 50 if not self._sorted_start_list: |
| 51 return None |
50 if not self._is_sorted: | 52 if not self._is_sorted: |
51 self._sorted_start_list.sort() | 53 self._sorted_start_list.sort() |
52 self._is_sorted = True | 54 self._is_sorted = True |
53 found_index = bisect.bisect_left(self._sorted_start_list, address) | 55 found_index = bisect.bisect_left(self._sorted_start_list, address) |
54 found_start_address = self._sorted_start_list[found_index - 1] | 56 found_start_address = self._sorted_start_list[found_index - 1] |
55 return self._symbol_map[found_start_address] | 57 return self._symbol_map[found_start_address] |
56 | 58 |
57 | 59 |
58 class Procedure(object): | 60 class Procedure(object): |
59 """A class for a procedure symbol and an address range for the symbol.""" | 61 """A class for a procedure symbol and an address range for the symbol.""" |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
112 return '%x+%x(%x) %s' % (self.address, self.size, self.offset, self.name) | 114 return '%x+%x(%x) %s' % (self.address, self.size, self.offset, self.name) |
113 | 115 |
114 | 116 |
115 class StaticSymbolsInFile(object): | 117 class StaticSymbolsInFile(object): |
116 """Represents static symbol information in a binary file.""" | 118 """Represents static symbol information in a binary file.""" |
117 | 119 |
118 def __init__(self, my_name): | 120 def __init__(self, my_name): |
119 self.my_name = my_name | 121 self.my_name = my_name |
120 self._elf_sections = [] | 122 self._elf_sections = [] |
121 self._procedures = RangeAddressMapping() | 123 self._procedures = RangeAddressMapping() |
| 124 self._sourcefiles = RangeAddressMapping() |
122 self._typeinfos = AddressMapping() | 125 self._typeinfos = AddressMapping() |
123 | 126 |
124 def _append_elf_section(self, elf_section): | 127 def _append_elf_section(self, elf_section): |
125 self._elf_sections.append(elf_section) | 128 self._elf_sections.append(elf_section) |
126 | 129 |
127 def _append_procedure(self, start, procedure): | 130 def _append_procedure(self, start, procedure): |
128 self._procedures.append(start, procedure) | 131 self._procedures.append(start, procedure) |
129 | 132 |
| 133 def _append_sourcefile(self, start, sourcefile): |
| 134 self._sourcefiles.append(start, sourcefile) |
| 135 |
130 def _append_typeinfo(self, start, typeinfo): | 136 def _append_typeinfo(self, start, typeinfo): |
131 self._typeinfos.append(start, typeinfo) | 137 self._typeinfos.append(start, typeinfo) |
132 | 138 |
133 def _find_symbol_by_runtime_address(self, address, vma, target): | 139 def _find_symbol_by_runtime_address(self, address, vma, target): |
134 if not (vma.begin <= address < vma.end): | 140 if not (vma.begin <= address < vma.end): |
135 return None | 141 return None |
136 | 142 |
137 if vma.name != self.my_name: | 143 if vma.name != self.my_name: |
138 return None | 144 return None |
139 | 145 |
140 file_offset = address - (vma.begin - vma.offset) | 146 file_offset = address - (vma.begin - vma.offset) |
141 elf_address = None | 147 elf_address = None |
142 for section in self._elf_sections: | 148 for section in self._elf_sections: |
143 if section.offset <= file_offset < (section.offset + section.size): | 149 if section.offset <= file_offset < (section.offset + section.size): |
144 elf_address = section.address + file_offset - section.offset | 150 elf_address = section.address + file_offset - section.offset |
145 if not elf_address: | 151 if not elf_address: |
146 return None | 152 return None |
147 | 153 |
148 return target.find(elf_address) | 154 return target.find(elf_address) |
149 | 155 |
150 def find_procedure_by_runtime_address(self, address, vma): | 156 def find_procedure_by_runtime_address(self, address, vma): |
151 return self._find_symbol_by_runtime_address(address, vma, self._procedures) | 157 return self._find_symbol_by_runtime_address(address, vma, self._procedures) |
152 | 158 |
| 159 def find_sourcefile_by_runtime_address(self, address, vma): |
| 160 return self._find_symbol_by_runtime_address(address, vma, self._sourcefiles) |
| 161 |
153 def find_typeinfo_by_runtime_address(self, address, vma): | 162 def find_typeinfo_by_runtime_address(self, address, vma): |
154 return self._find_symbol_by_runtime_address(address, vma, self._typeinfos) | 163 return self._find_symbol_by_runtime_address(address, vma, self._typeinfos) |
155 | 164 |
156 def load_readelf_ew(self, f): | 165 def load_readelf_ew(self, f): |
157 found_header = False | 166 found_header = False |
158 for line in f: | 167 for line in f: |
159 if line.rstrip() == 'Section Headers:': | 168 if line.rstrip() == 'Section Headers:': |
160 found_header = True | 169 found_header = True |
161 break | 170 break |
162 if not found_header: | 171 if not found_header: |
(...skipping 13 matching lines...) Expand all Loading... |
176 matched.group(7), # es | 185 matched.group(7), # es |
177 matched.group(8), # flg | 186 matched.group(8), # flg |
178 matched.group(9), # lk | 187 matched.group(9), # lk |
179 matched.group(10), # inf | 188 matched.group(10), # inf |
180 matched.group(11) # al | 189 matched.group(11) # al |
181 )) | 190 )) |
182 else: | 191 else: |
183 if line in ('Key to Flags:', 'Program Headers:'): | 192 if line in ('Key to Flags:', 'Program Headers:'): |
184 break | 193 break |
185 | 194 |
| 195 def load_readelf_debug_decodedline_file(self, input_file): |
| 196 for line in input_file: |
| 197 splitted = line.rstrip().split(None, 2) |
| 198 self._append_sourcefile(int(splitted[0], 16), splitted[1]) |
| 199 |
186 @staticmethod | 200 @staticmethod |
187 def _parse_nm_bsd_line(line): | 201 def _parse_nm_bsd_line(line): |
188 if line[8] == ' ': | 202 if line[8] == ' ': |
189 return line[0:8], line[9], line[11:] | 203 return line[0:8], line[9], line[11:] |
190 elif line[16] == ' ': | 204 elif line[16] == ' ': |
191 return line[0:16], line[17], line[19:] | 205 return line[0:16], line[17], line[19:] |
192 raise ParsingException('Invalid nm output.') | 206 raise ParsingException('Invalid nm output.') |
193 | 207 |
194 @staticmethod | 208 @staticmethod |
195 def _get_short_function_name(function): | 209 def _get_short_function_name(function): |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
254 self._append_procedure( | 268 self._append_procedure( |
255 last_start, Procedure(last_start, start_val, routine)) | 269 last_start, Procedure(last_start, start_val, routine)) |
256 | 270 |
257 last_start = start_val | 271 last_start = start_val |
258 routine = sym_name | 272 routine = sym_name |
259 | 273 |
260 if not mangled: | 274 if not mangled: |
261 routine = self._get_short_function_name(routine) | 275 routine = self._get_short_function_name(routine) |
262 self._append_procedure( | 276 self._append_procedure( |
263 last_start, Procedure(last_start, last_start, routine)) | 277 last_start, Procedure(last_start, last_start, routine)) |
OLD | NEW |