| OLD | NEW |
| 1 # Copyright 2017 The Chromium Authors. All rights reserved. | 1 # Copyright 2017 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
| 4 | 4 |
| 5 """Main Python API for analyzing binary size.""" | 5 """Main Python API for analyzing binary size.""" |
| 6 | 6 |
| 7 import argparse | 7 import argparse |
| 8 import calendar | 8 import calendar |
| 9 import collections | 9 import collections |
| 10 import datetime | 10 import datetime |
| (...skipping 531 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 542 # Matches [ 2] .hash HASH 00000000006681f0 0001f0 003154 04 A 3 0 8 | 542 # Matches [ 2] .hash HASH 00000000006681f0 0001f0 003154 04 A 3 0 8 |
| 543 for match in re.finditer(r'\[[\s\d]+\] (\..*)$', stdout, re.MULTILINE): | 543 for match in re.finditer(r'\[[\s\d]+\] (\..*)$', stdout, re.MULTILINE): |
| 544 items = match.group(1).split() | 544 items = match.group(1).split() |
| 545 section_sizes[items[0]] = int(items[4], 16) | 545 section_sizes[items[0]] = int(items[4], 16) |
| 546 return section_sizes | 546 return section_sizes |
| 547 | 547 |
| 548 | 548 |
| 549 def _ArchFromElf(elf_path, tool_prefix): | 549 def _ArchFromElf(elf_path, tool_prefix): |
| 550 args = [tool_prefix + 'readelf', '-h', elf_path] | 550 args = [tool_prefix + 'readelf', '-h', elf_path] |
| 551 stdout = subprocess.check_output(args) | 551 stdout = subprocess.check_output(args) |
| 552 return re.search('Machine:\s*(\S+)', stdout).group(1) | 552 machine = re.search('Machine:\s*(.+)', stdout).group(1) |
| 553 if machine == 'Intel 80386': |
| 554 return 'x86' |
| 555 if machine == 'Advanced Micro Devices X86-64': |
| 556 return 'x64' |
| 557 elif machine == 'ARM': |
| 558 return 'arm' |
| 559 elif machine == 'AArch64': |
| 560 return 'arm64' |
| 561 return machine |
| 553 | 562 |
| 554 | 563 |
| 555 def _ParseGnArgs(args_path): | 564 def _ParseGnArgs(args_path): |
| 556 """Returns a list of normalized "key=value" strings.""" | 565 """Returns a list of normalized "key=value" strings.""" |
| 557 args = {} | 566 args = {} |
| 558 with open(args_path) as f: | 567 with open(args_path) as f: |
| 559 for l in f: | 568 for l in f: |
| 560 # Strips #s even if within string literal. Not a problem in practice. | 569 # Strips #s even if within string literal. Not a problem in practice. |
| 561 parts = l.split('#')[0].split('=') | 570 parts = l.split('#')[0].split('=') |
| 562 if len(parts) != 2: | 571 if len(parts) != 2: |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 657 if apk_path: | 666 if apk_path: |
| 658 logging.debug('Extracting section sizes from .so within .apk') | 667 logging.debug('Extracting section sizes from .so within .apk') |
| 659 unstripped_section_sizes = size_info.section_sizes | 668 unstripped_section_sizes = size_info.section_sizes |
| 660 apk_build_id, size_info.section_sizes = apk_elf_result.get() | 669 apk_build_id, size_info.section_sizes = apk_elf_result.get() |
| 661 assert apk_build_id == metadata[models.METADATA_ELF_BUILD_ID], ( | 670 assert apk_build_id == metadata[models.METADATA_ELF_BUILD_ID], ( |
| 662 'BuildID for %s within %s did not match the one at %s' % | 671 'BuildID for %s within %s did not match the one at %s' % |
| 663 (apk_so_path, apk_path, elf_path)) | 672 (apk_so_path, apk_path, elf_path)) |
| 664 | 673 |
| 665 packed_section_name = None | 674 packed_section_name = None |
| 666 architecture = metadata[models.METADATA_ELF_ARCHITECTURE] | 675 architecture = metadata[models.METADATA_ELF_ARCHITECTURE] |
| 667 if architecture == 'ARM': | 676 # Packing occurs enabled only arm32 & arm64. |
| 677 if architecture == 'arm': |
| 668 packed_section_name = '.rel.dyn' | 678 packed_section_name = '.rel.dyn' |
| 669 elif architecture == 'AArch64': | 679 elif architecture == 'arm64': |
| 670 packed_section_name = '.rela.dyn' | 680 packed_section_name = '.rela.dyn' |
| 671 | 681 |
| 672 if packed_section_name: | 682 if packed_section_name: |
| 673 logging.debug('Recording size of unpacked relocations') | 683 logging.debug('Recording size of unpacked relocations') |
| 674 if packed_section_name not in size_info.section_sizes: | 684 if packed_section_name not in size_info.section_sizes: |
| 675 logging.warning('Packed section not present: %s', packed_section_name) | 685 logging.warning('Packed section not present: %s', packed_section_name) |
| 676 else: | 686 else: |
| 677 size_info.section_sizes['%s (unpacked)' % packed_section_name] = ( | 687 size_info.section_sizes['%s (unpacked)' % packed_section_name] = ( |
| 678 unstripped_section_sizes.get(packed_section_name)) | 688 unstripped_section_sizes.get(packed_section_name)) |
| 679 | 689 |
| 680 logging.info('Recording metadata: \n %s', | 690 logging.info('Recording metadata: \n %s', |
| 681 '\n '.join(describe.DescribeMetadata(size_info.metadata))) | 691 '\n '.join(describe.DescribeMetadata(size_info.metadata))) |
| 682 logging.info('Saving result to %s', args.size_file) | 692 logging.info('Saving result to %s', args.size_file) |
| 683 file_format.SaveSizeInfo(size_info, args.size_file) | 693 file_format.SaveSizeInfo(size_info, args.size_file) |
| 684 logging.info('Done') | 694 logging.info('Done') |
| OLD | NEW |