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 |