| OLD | NEW |
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2012 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 import json | 6 import json |
| 7 import logging | 7 import logging |
| 8 import os | 8 import os |
| 9 import re | 9 import re |
| 10 import shutil | 10 import shutil |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 48 return None | 48 return None |
| 49 | 49 |
| 50 if not os.path.exists(filename_out): | 50 if not os.path.exists(filename_out): |
| 51 return None | 51 return None |
| 52 | 52 |
| 53 return filename_out | 53 return filename_out |
| 54 | 54 |
| 55 | 55 |
| 56 def prepare_symbol_info(maps_path, | 56 def prepare_symbol_info(maps_path, |
| 57 output_dir_path=None, | 57 output_dir_path=None, |
| 58 fake_directories=None, | 58 alternative_dirs=None, |
| 59 use_tempdir=False, | 59 use_tempdir=False, |
| 60 use_source_file_name=False): | 60 use_source_file_name=False): |
| 61 """Prepares (collects) symbol information files for find_runtime_symbols. | 61 """Prepares (collects) symbol information files for find_runtime_symbols. |
| 62 | 62 |
| 63 1) If |output_dir_path| is specified, it tries collecting symbol information | 63 1) If |output_dir_path| is specified, it tries collecting symbol information |
| 64 files in the given directory |output_dir_path|. | 64 files in the given directory |output_dir_path|. |
| 65 1-a) If |output_dir_path| doesn't exist, create the directory and use it. | 65 1-a) If |output_dir_path| doesn't exist, create the directory and use it. |
| 66 1-b) If |output_dir_path| is an empty directory, use it. | 66 1-b) If |output_dir_path| is an empty directory, use it. |
| 67 1-c) If |output_dir_path| is a directory which has 'files.json', assumes that | 67 1-c) If |output_dir_path| is a directory which has 'files.json', assumes that |
| 68 files are already collected and just ignores it. | 68 files are already collected and just ignores it. |
| 69 1-d) Otherwise, depends on |use_tempdir|. | 69 1-d) Otherwise, depends on |use_tempdir|. |
| 70 | 70 |
| 71 2) If |output_dir_path| is not specified, it tries to create a new directory | 71 2) If |output_dir_path| is not specified, it tries to create a new directory |
| 72 depending on 'maps_path'. | 72 depending on 'maps_path'. |
| 73 | 73 |
| 74 If it cannot create a new directory, creates a temporary directory depending | 74 If it cannot create a new directory, creates a temporary directory depending |
| 75 on |use_tempdir|. If |use_tempdir| is False, returns None. | 75 on |use_tempdir|. If |use_tempdir| is False, returns None. |
| 76 | 76 |
| 77 Args: | 77 Args: |
| 78 maps_path: A path to a file which contains '/proc/<pid>/maps'. | 78 maps_path: A path to a file which contains '/proc/<pid>/maps'. |
| 79 fake_directories: A mapping from a directory '/path/on/target' where the | 79 alternative_dirs: A mapping from a directory '/path/on/target' where the |
| 80 target process runs to a directory '/path/on/host' where the script | 80 target process runs to a directory '/path/on/host' where the script |
| 81 reads the binary. Considered to be used for Android binaries. | 81 reads the binary. Considered to be used for Android binaries. |
| 82 output_dir_path: A path to a directory where files are prepared. | 82 output_dir_path: A path to a directory where files are prepared. |
| 83 use_tempdir: If True, it creates a temporary directory when it cannot | 83 use_tempdir: If True, it creates a temporary directory when it cannot |
| 84 create a new directory. | 84 create a new directory. |
| 85 use_source_file_name: If True, it adds reduced result of 'readelf -wL' | 85 use_source_file_name: If True, it adds reduced result of 'readelf -wL' |
| 86 to find source file names. | 86 to find source file names. |
| 87 | 87 |
| 88 Returns: | 88 Returns: |
| 89 A pair of a path to the prepared directory and a boolean representing | 89 A pair of a path to the prepared directory and a boolean representing |
| 90 if it created a temporary directory or not. | 90 if it created a temporary directory or not. |
| 91 """ | 91 """ |
| 92 fake_directories = fake_directories or {} | 92 alternative_dirs = alternative_dirs or {} |
| 93 if not output_dir_path: | 93 if not output_dir_path: |
| 94 matched = re.match('^(.*)\.maps$', os.path.basename(maps_path)) | 94 matched = re.match('^(.*)\.maps$', os.path.basename(maps_path)) |
| 95 if matched: | 95 if matched: |
| 96 output_dir_path = matched.group(1) + '.pre' | 96 output_dir_path = matched.group(1) + '.pre' |
| 97 if not output_dir_path: | 97 if not output_dir_path: |
| 98 matched = re.match('^/proc/(.*)/maps$', os.path.realpath(maps_path)) | 98 matched = re.match('^/proc/(.*)/maps$', os.path.realpath(maps_path)) |
| 99 if matched: | 99 if matched: |
| 100 output_dir_path = matched.group(1) + '.pre' | 100 output_dir_path = matched.group(1) + '.pre' |
| 101 if not output_dir_path: | 101 if not output_dir_path: |
| 102 output_dir_path = os.path.basename(maps_path) + '.pre' | 102 output_dir_path = os.path.basename(maps_path) + '.pre' |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 138 | 138 |
| 139 with open(maps_path, mode='r') as f: | 139 with open(maps_path, mode='r') as f: |
| 140 maps = ProcMaps.load(f) | 140 maps = ProcMaps.load(f) |
| 141 | 141 |
| 142 LOGGER.debug('Listing up symbols.') | 142 LOGGER.debug('Listing up symbols.') |
| 143 files = {} | 143 files = {} |
| 144 for entry in maps.iter(ProcMaps.executable): | 144 for entry in maps.iter(ProcMaps.executable): |
| 145 LOGGER.debug(' %016x-%016x +%06x %s' % ( | 145 LOGGER.debug(' %016x-%016x +%06x %s' % ( |
| 146 entry.begin, entry.end, entry.offset, entry.name)) | 146 entry.begin, entry.end, entry.offset, entry.name)) |
| 147 binary_path = entry.name | 147 binary_path = entry.name |
| 148 for target_path, host_path in fake_directories.iteritems(): | 148 for target_path, host_path in alternative_dirs.iteritems(): |
| 149 if entry.name.startswith(target_path): | 149 if entry.name.startswith(target_path): |
| 150 binary_path = entry.name.replace(target_path, host_path, 1) | 150 binary_path = entry.name.replace(target_path, host_path, 1) |
| 151 nm_filename = _dump_command_result( | 151 nm_filename = _dump_command_result( |
| 152 'nm -n --format bsd %s | c++filt' % binary_path, | 152 'nm -n --format bsd %s | c++filt' % binary_path, |
| 153 output_dir_path, os.path.basename(binary_path), '.nm') | 153 output_dir_path, os.path.basename(binary_path), '.nm') |
| 154 if not nm_filename: | 154 if not nm_filename: |
| 155 continue | 155 continue |
| 156 readelf_e_filename = _dump_command_result( | 156 readelf_e_filename = _dump_command_result( |
| 157 'readelf -eW %s' % binary_path, | 157 'readelf -eW %s' % binary_path, |
| 158 output_dir_path, os.path.basename(binary_path), '.readelf-e') | 158 output_dir_path, os.path.basename(binary_path), '.readelf-e') |
| (...skipping 28 matching lines...) Expand all Loading... |
| 187 sys.stderr.write('This script work only on Linux.') | 187 sys.stderr.write('This script work only on Linux.') |
| 188 return 1 | 188 return 1 |
| 189 | 189 |
| 190 LOGGER.setLevel(logging.DEBUG) | 190 LOGGER.setLevel(logging.DEBUG) |
| 191 handler = logging.StreamHandler() | 191 handler = logging.StreamHandler() |
| 192 handler.setLevel(logging.INFO) | 192 handler.setLevel(logging.INFO) |
| 193 formatter = logging.Formatter('%(message)s') | 193 formatter = logging.Formatter('%(message)s') |
| 194 handler.setFormatter(formatter) | 194 handler.setFormatter(formatter) |
| 195 LOGGER.addHandler(handler) | 195 LOGGER.addHandler(handler) |
| 196 | 196 |
| 197 # TODO(dmikurube): Specify |fake_directories| from command line. | 197 # TODO(dmikurube): Specify |alternative_dirs| from command line. |
| 198 if len(sys.argv) < 2: | 198 if len(sys.argv) < 2: |
| 199 sys.stderr.write("""Usage: | 199 sys.stderr.write("""Usage: |
| 200 %s /path/to/maps [/path/to/output_data_dir/] | 200 %s /path/to/maps [/path/to/output_data_dir/] |
| 201 """ % sys.argv[0]) | 201 """ % sys.argv[0]) |
| 202 return 1 | 202 return 1 |
| 203 elif len(sys.argv) == 2: | 203 elif len(sys.argv) == 2: |
| 204 result, _ = prepare_symbol_info(sys.argv[1]) | 204 result, _ = prepare_symbol_info(sys.argv[1]) |
| 205 else: | 205 else: |
| 206 result, _ = prepare_symbol_info(sys.argv[1], sys.argv[2]) | 206 result, _ = prepare_symbol_info(sys.argv[1], sys.argv[2]) |
| 207 | 207 |
| 208 return not result | 208 return not result |
| 209 | 209 |
| 210 | 210 |
| 211 if __name__ == '__main__': | 211 if __name__ == '__main__': |
| 212 sys.exit(main()) | 212 sys.exit(main()) |
| OLD | NEW |