Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # Copyright (c) 2013 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2013 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 """Reduces result of 'readelf -wL' to just a set of address ranges per file. | 5 """Reduces result of 'readelf -wL' to just a list of starting addresses. |
| 6 | 6 |
| 7 For example: | 7 It lists up all addresses where the corresponding source files change. The |
| 8 | 8 list is sorted in ascending order. See tests/reduce_debugline_test.py for |
| 9 CU: ../../chrome_main.cc: | 9 examples. |
| 10 File name Line number Starting address | |
| 11 chrome_main.cc 30 0xa3be90 | |
| 12 (an empty line) | |
| 13 chrome_main.cc 31 0xa3bea3 | |
| 14 chrome_main.cc 32 0xa3beaf | |
| 15 chrome_main.cc 34 0xa3bec9 | |
| 16 chrome_main.cc 32 0xa3bed1 | |
| 17 (an empty line) | |
| 18 | |
| 19 The example above is reduced into: | |
| 20 {'../../chrome_main.cc', [(0xa3be90, 0xa3be90), (0xa3bea3, 0xa3bed1)]} | |
| 21 where (0xa3bea3, 0xa3bed1) means an address range from 0xa3bea3 to 0xa3bed1. | |
| 22 | 10 |
| 23 This script assumes that the result of 'readelf -wL' ends with an empty line. | 11 This script assumes that the result of 'readelf -wL' ends with an empty line. |
| 24 | 12 |
| 25 Note: the option '-wL' has the same meaning with '--debug-dump=decodedline'. | 13 Note: the option '-wL' has the same meaning with '--debug-dump=decodedline'. |
| 26 """ | 14 """ |
| 27 | 15 |
| 28 import re | 16 import re |
| 29 import sys | 17 import sys |
| 30 | 18 |
| 31 | 19 |
| 32 _FILENAME_PATTERN = re.compile('(CU: |)(.+)\:') | 20 _FILENAME_PATTERN = re.compile('(CU: |)(.+)\:') |
| 33 | 21 |
| 34 | 22 |
| 35 def reduce_decoded_debugline(input_file): | 23 def reduce_decoded_debugline(input_file): |
| 36 filename = '' | 24 filename = '' |
| 37 ranges_dict = {} | 25 starting_dict = {} |
| 38 starting = None | 26 started = False |
| 39 ending = None | |
| 40 | 27 |
| 41 for line in input_file: | 28 for line in input_file: |
| 42 line = line.strip() | 29 line = line.strip() |
| 30 unpacked = line.split(None, 2) | |
| 43 | 31 |
| 44 if line.endswith(':'): | 32 if len(unpacked) == 3 and unpacked[2].startswith('0x'): |
| 45 matched = _FILENAME_PATTERN.match(line) | 33 if not started and filename: |
| 46 if matched: | 34 started = True |
| 47 filename = matched.group(2) | 35 starting_dict[int(unpacked[2], 16)] = filename |
| 48 continue | 36 else: |
| 37 started = False | |
| 38 if line.endswith(':'): | |
| 39 matched = _FILENAME_PATTERN.match(line) | |
| 40 if matched: | |
| 41 filename = matched.group(2) | |
| 49 | 42 |
| 50 unpacked = line.split(None, 2) | 43 starting_list = [] |
| 51 if len(unpacked) != 3 or not unpacked[2].startswith('0x'): | 44 prev_filename = '' |
| 52 if starting: | 45 for address in sorted(starting_dict.keys()): |
|
M-A Ruel
2013/04/09 03:09:04
for address in sorted(starting_dict):
Dai Mikurube (NOT FULLTIME)
2013/04/09 04:15:58
Done.
| |
| 53 ranges_dict.setdefault(filename, []).append((starting, ending)) | 46 curr_filename = starting_dict[address] |
| 54 starting = None | 47 if prev_filename != curr_filename: |
| 55 ending = None | 48 starting_list.append((address, starting_dict[address])) |
| 56 continue | 49 prev_filename = curr_filename |
| 57 | 50 return starting_list |
| 58 ending = int(unpacked[2], 16) | |
| 59 if not starting: | |
| 60 starting = ending | |
| 61 | |
| 62 if starting or ending: | |
| 63 raise ValueError('No new line at last.') | |
| 64 | |
| 65 return ranges_dict | |
| 66 | 51 |
| 67 | 52 |
| 68 def main(): | 53 def main(): |
| 69 if len(sys.argv) != 1: | 54 if len(sys.argv) != 1: |
| 70 print >> sys.stderr, 'Unsupported arguments' | 55 print >> sys.stderr, 'Unsupported arguments' |
| 71 return 1 | 56 return 1 |
| 72 | 57 |
| 73 ranges_dict = reduce_decoded_debugline(sys.stdin) | 58 starting_list = reduce_decoded_debugline(sys.stdin) |
| 74 for filename, ranges in ranges_dict.iteritems(): | 59 bits64 = True if starting_list[-1][0] > 0xffffffff else False |
|
M-A Ruel
2013/04/09 03:09:04
bits64 = (starting_list[-1][0] > 0xffffffff)
Dai Mikurube (NOT FULLTIME)
2013/04/09 04:15:58
Done.
| |
| 75 print filename + ':' | 60 for address, filename in starting_list: |
| 76 prev = (0, 0) | 61 if bits64: |
| 77 for address_range in sorted(ranges): | 62 print '%016x %s' % (address, filename) |
| 78 if address_range == prev: | 63 else: |
| 79 continue | 64 print '%08x %s' % (address, filename) |
| 80 print ' %x-%x' % (address_range[0], address_range[1]) | |
| 81 prev = address_range | |
| 82 | 65 |
| 83 | 66 |
| 84 if __name__ == '__main__': | 67 if __name__ == '__main__': |
| 85 sys.exit(main()) | 68 sys.exit(main()) |
| OLD | NEW |