parse_link_map.py
Go to the documentation of this file.
1 #!/usr/bin/python
2 # Copyright 2018 gRPC authors.
3 #
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
7 #
8 # http://www.apache.org/licenses/LICENSE-2.0
9 #
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15 
16 # This script analyzes link map file generated by Xcode. It calculates and
17 # prints out the sizes of each dependent library and the total sizes of the
18 # symbols.
19 # The script takes one parameter, which is the path to the link map file.
20 
21 import re
22 import sys
23 
24 
25 def parse_link_map(filename):
26  table_tag = {}
27  state = "start"
28 
29  table_stats_symbol = {}
30  table_stats_dead = {}
31  section_total_size = 0
32  symbol_total_size = 0
33 
34  boringssl_size = 0
35  core_size = 0
36  objc_size = 0
37  protobuf_size = 0
38 
39  lines = open(filename, encoding='utf-8', errors='ignore').readlines()
40  for line in lines:
41  line_stripped = line[:-1]
42  if "# Object files:" == line_stripped:
43  state = "object"
44  continue
45  elif "# Sections:" == line_stripped:
46  state = "section"
47  continue
48  elif "# Symbols:" == line_stripped:
49  state = "symbol"
50  continue
51  elif "# Dead Stripped Symbols:" == line_stripped:
52  state = "dead"
53  continue
54 
55  if state == "object":
56  segs = re.search('(\[ *[0-9]*\]) (.*)', line_stripped)
57  table_tag[segs.group(1)] = segs.group(2)
58 
59  if state == "section":
60  if len(line_stripped) == 0 or line_stripped[0] == '#':
61  continue
62  segs = re.search('^(.+?)\s+(.+?)\s+.*', line_stripped)
63  section_total_size += int(segs.group(2), 16)
64 
65  if state == "symbol":
66  if len(line_stripped) == 0 or line_stripped[0] == '#':
67  continue
68  segs = re.search('^.+?\s+(.+?)\s+(\[.+?\]).*', line_stripped)
69  if not segs:
70  continue
71  target = table_tag[segs.group(2)]
72  target_stripped = re.search('^(.*?)(\(.+?\))?$', target).group(1)
73  size = int(segs.group(1), 16)
74  if not target_stripped in table_stats_symbol:
75  table_stats_symbol[target_stripped] = 0
76  table_stats_symbol[target_stripped] += size
77  if 'BoringSSL' in target_stripped:
78  boringssl_size += size
79  elif 'libgRPC-Core' in target_stripped:
80  core_size += size
81  elif 'libgRPC-RxLibrary' in target_stripped or \
82  'libgRPC' in target_stripped or \
83  'libgRPC-ProtoLibrary' in target_stripped:
84  objc_size += size
85  elif 'libProtobuf' in target_stripped:
86  protobuf_size += size
87 
88  for target in table_stats_symbol:
89  symbol_total_size += table_stats_symbol[target]
90 
91  return core_size, objc_size, boringssl_size, protobuf_size, symbol_total_size
92 
93 
94 def main():
95  filename = sys.argv[1]
96  core_size, objc_size, boringssl_size, protobuf_size, total_size = parse_link_map(
97  filename)
98  print(('Core size:{:,}'.format(core_size)))
99  print(('ObjC size:{:,}'.format(objc_size)))
100  print(('BoringSSL size:{:,}'.format(boringssl_size)))
101  print(('Protobuf size:{:,}\n'.format(protobuf_size)))
102  print(('Total size:{:,}'.format(total_size)))
103 
104 
105 if __name__ == "__main__":
106  main()
http2_test_server.format
format
Definition: http2_test_server.py:118
xds_interop_client.int
int
Definition: xds_interop_client.py:113
upload.group
group
Definition: bloaty/third_party/googletest/googlemock/scripts/upload.py:397
main
Definition: main.py:1
open
#define open
Definition: test-fs.c:46
len
int len
Definition: abseil-cpp/absl/base/internal/low_level_alloc_test.cc:46


grpc
Author(s):
autogenerated on Thu Mar 13 2025 03:00:49