| OLD | NEW |
| (Empty) |
| 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 | |
| 3 # found in the LICENSE file. | |
| 4 | |
| 5 """Deals with loading & saving .size files.""" | |
| 6 | |
| 7 import ast | |
| 8 import gzip | |
| 9 import models | |
| 10 | |
| 11 | |
| 12 # File format version for .size files. | |
| 13 _SERIALIZATION_VERSION = 1 | |
| 14 | |
| 15 | |
| 16 def EndsWithMaybeGz(path, suffix): | |
| 17 return path.endswith(suffix) or path.endswith(suffix + '.gz') | |
| 18 | |
| 19 | |
| 20 def OpenMaybeGz(path, mode=None): | |
| 21 """Calls `gzip.open()` if |path| ends in ".gz", otherwise calls `open()`.""" | |
| 22 if path.endswith('.gz'): | |
| 23 if mode and 'w' in mode: | |
| 24 return gzip.GzipFile(path, mode, 1) | |
| 25 return gzip.open(path, mode) | |
| 26 return open(path, mode or 'r') | |
| 27 | |
| 28 | |
| 29 def _SaveSizeInfoToFile(result, file_obj): | |
| 30 """Saves the result to the given file object.""" | |
| 31 # Store one bucket per line. | |
| 32 file_obj.write('%d\n' % _SERIALIZATION_VERSION) | |
| 33 file_obj.write('%r\n' % result.section_sizes) | |
| 34 file_obj.write('%d\n' % len(result.symbols)) | |
| 35 prev_section_name = None | |
| 36 # Store symbol fields as tab-separated. | |
| 37 # Store only non-derived fields. | |
| 38 for symbol in result.symbols: | |
| 39 if symbol.section_name != prev_section_name: | |
| 40 file_obj.write('%s\n' % symbol.section_name) | |
| 41 prev_section_name = symbol.section_name | |
| 42 # Don't write padding nor name since these are derived values. | |
| 43 file_obj.write('%x\t%x\t%s\t%s\n' % ( | |
| 44 symbol.address, symbol.size_without_padding, | |
| 45 symbol.function_signature or symbol.name, symbol.path)) | |
| 46 | |
| 47 | |
| 48 def _LoadSizeInfoFromFile(file_obj): | |
| 49 """Loads a result from the given file.""" | |
| 50 lines = iter(file_obj) | |
| 51 actual_version = int(next(lines)) | |
| 52 assert actual_version == _SERIALIZATION_VERSION, ( | |
| 53 'Version mismatch. Need to write some upgrade code.') | |
| 54 | |
| 55 section_sizes = ast.literal_eval(next(lines)) | |
| 56 num_syms = int(next(lines)) | |
| 57 symbol_list = [None] * num_syms | |
| 58 section_name = None | |
| 59 for i in xrange(num_syms): | |
| 60 line = next(lines)[:-1] | |
| 61 if '\t' not in line: | |
| 62 section_name = line | |
| 63 line = next(lines)[:-1] | |
| 64 new_sym = models.Symbol.__new__(models.Symbol) | |
| 65 parts = line.split('\t') | |
| 66 new_sym.section_name = section_name | |
| 67 new_sym.address = int(parts[0], 16) | |
| 68 new_sym.size = int(parts[1], 16) | |
| 69 new_sym.name = parts[2] | |
| 70 new_sym.path = parts[3] | |
| 71 new_sym.padding = 0 # Derived | |
| 72 new_sym.function_signature = None # Derived | |
| 73 symbol_list[i] = new_sym | |
| 74 | |
| 75 return models.SizeInfo(models.SymbolGroup(symbol_list), section_sizes) | |
| 76 | |
| 77 | |
| 78 def SaveSizeInfo(result, path): | |
| 79 with OpenMaybeGz(path, 'wb') as f: | |
| 80 _SaveSizeInfoToFile(result, f) | |
| 81 | |
| 82 | |
| 83 def LoadSizeInfo(path): | |
| 84 with OpenMaybeGz(path) as f: | |
| 85 return _LoadSizeInfoFromFile(f) | |
| OLD | NEW |