Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2)

Side by Side Diff: tools/cygprofile/symbol_extractor.py

Issue 886563002: Switch from nm to objdump for the cygprofile tools. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Typo. Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 #!/usr/bin/python 1 #!/usr/bin/python
2 # Copyright 2015 The Chromium Authors. All rights reserved. 2 # Copyright 2015 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 5
6 """Utilities to get and manipulate symbols from a binary.""" 6 """Utilities to get and manipulate symbols from a binary."""
7 7
8 import collections 8 import collections
9 import os 9 import os
10 import re 10 import re
11 import subprocess 11 import subprocess
12 import sys 12 import sys
13 13
14 sys.path.insert( 14 sys.path.insert(
15 0, os.path.join(sys.path[0], '..', '..', 'third_party', 'android_platform', 15 0, os.path.join(os.path.dirname(__file__), os.pardir, os.pardir,
16 'development', 'scripts')) 16 'third_party', 'android_platform', 'development',
17 'scripts'))
17 import symbol 18 import symbol
18 19
19 20
20 # TODO(lizeb): Change symbol.ARCH to the proper value when "arm" is no longer 21 # TODO(lizeb): Change symbol.ARCH to the proper value when "arm" is no longer
21 # the only possible value. 22 # the only possible value.
22 _NM_BINARY = symbol.ToolPath('nm') 23 _OBJDUMP_BINARY = symbol.ToolPath('objdump')
23 24
24 25
25 SymbolInfo = collections.namedtuple('SymbolInfo', ('name', 'offset', 'size')) 26 SymbolInfo = collections.namedtuple('SymbolInfo', ('name', 'offset', 'size',
27 'section'))
26 28
27 29
28 def FromNmLine(line): 30 def _FromObjdumpLine(line):
29 """Create a SymbolInfo by parsing a properly formatted nm output line. 31 """Create a SymbolInfo by parsing a properly formatted objdump output line.
30 32
31 Args: 33 Args:
32 line: line from nm 34 line: line from objdump
33 35
34 Returns: 36 Returns:
35 An instance of SymbolInfo if the line represents a symbol, None otherwise. 37 An instance of SymbolInfo if the line represents a symbol, None otherwise.
36 """ 38 """
37 # We are interested in two types of lines: 39 # All of the symbol lines we care about are in the form
38 # This: 40 # 0000000000 g F .text.foo 000000000 [.hidden] foo
39 # 00210d59 00000002 t _ZN34BrowserPluginHostMsg_Attach_ParamsD2Ev 41 # where g (global) might also be l (local) or w (weak).
40 # offset size <symbol_type> symbol_name
41 # And that:
42 # 0070ee8c T WebRtcSpl_ComplexBitReverse
43 # In the second case we don't have a size, so use -1 as a sentinel
44 if not re.search(' (t|W|T) ', line):
45 return None
46 parts = line.split() 42 parts = line.split()
47 if len(parts) == 4: 43 if len(parts) < 6 or parts[2] != 'F':
48 return SymbolInfo(
49 offset=int(parts[0], 16), size=int(parts[1], 16), name=parts[3])
50 elif len(parts) == 3:
51 return SymbolInfo(
52 offset=int(parts[0], 16), size=-1, name=parts[2])
53 else:
54 return None 44 return None
55 45
46 assert len(parts) == 6 or (len(parts) == 7 and parts[5] == '.hidden')
47 accepted_scopes = set(['g', 'l', 'w'])
48 assert parts[1] in accepted_scopes
56 49
57 def SymbolInfosFromStream(nm_lines): 50 offset = int(parts[0], 16)
58 """Parses the output of nm, and get all the symbols from a binary. 51 section = parts[3]
52 size = int(parts[4], 16)
53 name = parts[-1].rstrip('\n')
54 assert re.match('^[a-zA-Z0-9_.]+$', name)
55 return SymbolInfo(name=name, offset=offset, section=section, size=size)
56
57
58 def _SymbolInfosFromStream(objdump_lines):
59 """Parses the output of objdump, and get all the symbols from a binary.
59 60
60 Args: 61 Args:
61 nm_lines: An iterable of lines 62 objdump_lines: An iterable of lines
62 63
63 Returns: 64 Returns:
64 A list of SymbolInfo. 65 A list of SymbolInfo.
65 """ 66 """
66 # TODO(lizeb): Consider switching to objdump to simplify parsing.
67 symbol_infos = [] 67 symbol_infos = []
68 for line in nm_lines: 68 for line in objdump_lines:
69 symbol_info = FromNmLine(line) 69 symbol_info = _FromObjdumpLine(line)
70 if symbol_info is not None: 70 if symbol_info is not None:
71 symbol_infos.append(symbol_info) 71 symbol_infos.append(symbol_info)
72 return symbol_infos 72 return symbol_infos
73 73
74 74
75 def SymbolInfosFromBinary(binary_filename): 75 def SymbolInfosFromBinary(binary_filename):
76 """Runs nm to get all the symbols from a binary. 76 """Runs objdump to get all the symbols from a binary.
77 77
78 Args: 78 Args:
79 binary_filename: path to the binary. 79 binary_filename: path to the binary.
80 80
81 Returns: 81 Returns:
82 A list of SymbolInfo from the binary. 82 A list of SymbolInfo from the binary.
83 """ 83 """
84 command = (_NM_BINARY, '-S', '-n', binary_filename) 84 command = (_OBJDUMP_BINARY, '-t', '-w', binary_filename)
85 p = subprocess.Popen(command, shell=False, stdout=subprocess.PIPE) 85 p = subprocess.Popen(command, shell=False, stdout=subprocess.PIPE)
86 try: 86 try:
87 result = SymbolInfosFromStream(p.stdout) 87 result = _SymbolInfosFromStream(p.stdout)
88 return result 88 return result
89 finally: 89 finally:
90 p.wait() 90 p.wait()
91 91
92 92
93 def GroupSymbolInfosByOffset(symbol_infos): 93 def GroupSymbolInfosByOffset(symbol_infos):
94 """Create a dict {offset: [symbol_info1, ...], ...}. 94 """Create a dict {offset: [symbol_info1, ...], ...}.
95 95
96 As several symbols can be at the same offset, this is a 1-to-many 96 As several symbols can be at the same offset, this is a 1-to-many
97 relationship. 97 relationship.
(...skipping 13 matching lines...) Expand all
111 def CreateNameToSymbolInfo(symbol_infos): 111 def CreateNameToSymbolInfo(symbol_infos):
112 """Create a dict {name: symbol_info, ...}. 112 """Create a dict {name: symbol_info, ...}.
113 113
114 Args: 114 Args:
115 symbol_infos: iterable of SymbolInfo instances 115 symbol_infos: iterable of SymbolInfo instances
116 116
117 Returns: 117 Returns:
118 a dict {name: symbol_info, ...} 118 a dict {name: symbol_info, ...}
119 """ 119 """
120 return {symbol_info.name: symbol_info for symbol_info in symbol_infos} 120 return {symbol_info.name: symbol_info for symbol_info in symbol_infos}
OLDNEW
« no previous file with comments | « tools/cygprofile/patch_orderfile_unittest.py ('k') | tools/cygprofile/symbol_extractor_unittest.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698