- add sources.
[platform/framework/web/crosswalk.git] / src / tools / find_runtime_symbols / proc_maps.py
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
3 # found in the LICENSE file.
4
5 import re
6
7
8 _MAPS_PATTERN = re.compile(
9     r'^([a-f0-9]+)-([a-f0-9]+)\s+(.)(.)(.)(.)\s+([a-f0-9]+)\s+(\S+):(\S+)\s+'
10     r'(\d+)\s*(.*)$', re.IGNORECASE)
11
12
13 class ProcMapsEntry(object):
14   """A class representing one line in /proc/.../maps."""
15
16   def __init__(
17       self, begin, end, readable, writable, executable, private, offset,
18       major, minor, inode, name):
19     self.begin = begin
20     self.end = end
21     self.readable = readable
22     self.writable = writable
23     self.executable = executable
24     self.private = private
25     self.offset = offset
26     self.major = major
27     self.minor = minor
28     self.inode = inode
29     self.name = name
30
31   def as_dict(self):
32     return {
33         'begin': self.begin,
34         'end': self.end,
35         'readable': self.readable,
36         'writable': self.writable,
37         'executable': self.executable,
38         'private': self.private,
39         'offset': self.offset,
40         'major': self.major,
41         'minor': self.minor,
42         'inode': self.inode,
43         'name': self.name,
44     }
45
46
47 class ProcMaps(object):
48   """A class representing contents in /proc/.../maps."""
49
50   def __init__(self):
51     self._sorted_indexes = []
52     self._dictionary = {}
53     self._sorted = True
54
55   def iter(self, condition):
56     if not self._sorted:
57       self._sorted_indexes.sort()
58       self._sorted = True
59     for index in self._sorted_indexes:
60       if not condition or condition(self._dictionary[index]):
61         yield self._dictionary[index]
62
63   def __iter__(self):
64     if not self._sorted:
65       self._sorted_indexes.sort()
66       self._sorted = True
67     for index in self._sorted_indexes:
68       yield self._dictionary[index]
69
70   @staticmethod
71   def load(f):
72     table = ProcMaps()
73     for line in f:
74       table.append_line(line)
75     return table
76
77   def append_line(self, line):
78     entry = self.parse_line(line)
79     if entry:
80       self._append_entry(entry)
81
82   @staticmethod
83   def parse_line(line):
84     matched = _MAPS_PATTERN.match(line)
85     if matched:
86       return ProcMapsEntry(  # pylint: disable=W0212
87           int(matched.group(1), 16),  # begin
88           int(matched.group(2), 16),  # end
89           matched.group(3),           # readable
90           matched.group(4),           # writable
91           matched.group(5),           # executable
92           matched.group(6),           # private
93           int(matched.group(7), 16),  # offset
94           matched.group(8),           # major
95           matched.group(9),           # minor
96           int(matched.group(10), 10), # inode
97           matched.group(11)           # name
98           )
99     else:
100       return None
101
102   @staticmethod
103   def constants(entry):
104     return (entry.writable == '-' and entry.executable == '-' and re.match(
105         '\S+(\.(so|dll|dylib|bundle)|chrome)((\.\d+)+\w*(\.\d+){0,3})?',
106         entry.name))
107
108   @staticmethod
109   def executable(entry):
110     return (entry.executable == 'x' and re.match(
111         '\S+(\.(so|dll|dylib|bundle)|chrome)((\.\d+)+\w*(\.\d+){0,3})?',
112         entry.name))
113
114   @staticmethod
115   def executable_and_constants(entry):
116     return (((entry.writable == '-' and entry.executable == '-') or
117              entry.executable == 'x') and re.match(
118         '\S+(\.(so|dll|dylib|bundle)|chrome)((\.\d+)+\w*(\.\d+){0,3})?',
119         entry.name))
120
121   def _append_entry(self, entry):
122     if self._sorted_indexes and self._sorted_indexes[-1] > entry.begin:
123       self._sorted = False
124     self._sorted_indexes.append(entry.begin)
125     self._dictionary[entry.begin] = entry