def find_line_map(self, file_name): rpath = tuple(reversed(file_name.split(bsep))) try: lm, _ = trie_find(self.srcmap, rpath) except KeyError: try: cu = self.get_CU_by_reversed_path(rpath) except (KeyError, ValueError): # XXX: headers are not supported yet raise ValueError("Cannot find line program for file %s" % ( file_name )) self.account_line_program_CU(cu) lm, _ = trie_find(self.srcmap, rpath) except ValueError: raise ValueError("File name suffix '%s' is not long enough to" " unambiguously identify line map" % file_name) return lm
def _find_git_diff(self, version, fname): try: val, _ = trie_find(self._draft_diffs[version], tuple(reversed(fname.split(bsep)))) except KeyError: return identity_map, None else: if val[0] is not None: diff, rename = val # conversion of git diff information into delta intervals val = (git_diff2delta_intervals(diff), rename) return val
def get_glv_data(self, version, fname): "data is delta intervals and renaming for `fname`" version_trie = self._cache.setdefault(version, {}) try: return trie_find(version_trie, tuple(reversed(fname.split(bsep))))[0] except KeyError: pass if version not in self._draft_diffs: self._add_git_diff(version) val = self._find_git_diff(version, fname) trie_add(version_trie, tuple(reversed(fname.split(bsep))), val) return val
def line_map(self): """ Mapping from addresses to line program entries (DWARF) describing source code of that subprogram. """ die = self.die attrs = die.attributes if "DW_AT_decl_file" in attrs: decl_file = die.attributes["DW_AT_decl_file"].value else: decl_file = 0 if not decl_file: raise ValueError("No source file has been specified") if "DW_AT_decl_line" in attrs: decl_line = die.attributes["DW_AT_decl_line"].value else: decl_line = 0 if not decl_line: raise ValueError("No source line has been specified") dic = self.dic source_path = dic.get_CU_files(die.cu)[decl_file - 1] rpath = tuple(reversed(source_path)) # line program for the CU must be already accounted by `get_CU_files` lm, _ = trie_find(dic.srcmap, rpath) ranges = self.ranges line_map = intervalmap() cur = decl_line while cur: entries = lm[cur] for e in entries: addr = e.state.address for l, h in ranges: if l <= addr and addr < h: break else: # Address is not within the subroutine. continue # At least one address is within the subroutine break else: # All entries are outside the subroutine address ranges. # `cur`rent line is after the subroutine. Hence, consequent # lines are too. break _next = lm.right_bound(cur) line_map[cur:_next] = entries cur = _next return line_map