blob: 8c91d70a5a413a998e4de54a930b2b22d7963126 [file] [log] [blame]
xiaohu.huangffae1712022-11-01 18:04:01 +08001#!/usr/bin/python3
2#coding:utf-8
3#
4# Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
5#
6# SPDX-License-Identifier: MIT
7#
8
9
10from __future__ import print_function
11
12import sys
13import os
14import argparse
15
16parser = argparse.ArgumentParser(description='total size of each object file in an ld linker map.')
17parser.add_argument('map_file', help="A map file generated by passing -M/--print-map to ld during linking.")
18parser.add_argument('--combine', action='store_true',
19 help="All object files in an .a archive or in a directory are combined")
20args = parser.parse_args()
21
xiaohu.huang1f337742023-04-20 17:06:31 +080022class SectionSize:
xiaohu.huangffae1712022-11-01 18:04:01 +080023 text = 0
24 rela_text = 0
25 data = 0 # Including metadata like import tables
26 bss = 0
27 customize = 0
xiaohu.huang1f337742023-04-20 17:06:31 +080028 system_heap = 0
29 system_stack = 0
xiaohu.huangffae1712022-11-01 18:04:01 +080030 def rom(self):
31 return self.text + self.data
32 def ram(self):
33 return self.data + self.bss
34 def total(self):
35 return self.text + self.data + self.bss
xiaohu.huange6c31672022-12-05 10:10:42 +080036 def add_gcc_section(self, section, size):
xiaohu.huangfc139972024-01-23 10:36:50 +080037 if current_section is None:
38 return;
xiaohu.huangffae1712022-11-01 18:04:01 +080039 if section.startswith('.comment'):
40 return
41 if section.startswith('.debug'):
42 return
43 if section.startswith('.ARM.attributes'):
44 return
45 if section.startswith('.text'):
46 self.text += size
47 elif section.startswith('.rela.dyn'):
48 self.rela_text += size
49 elif section.startswith('.bss') or section.startswith('.common') or section.startswith('.sbss'):
50 self.bss += size
51 elif section.startswith('.data') or section.startswith('.rodata'):
52 self.data += size
53 elif section.startswith('.heap'):
xiaohu.huang1f337742023-04-20 17:06:31 +080054 SectionSize.system_heap += size
xiaohu.huangffae1712022-11-01 18:04:01 +080055 elif section.startswith('.stack'):
xiaohu.huang1f337742023-04-20 17:06:31 +080056 SectionSize.system_stack += size
xiaohu.huangffae1712022-11-01 18:04:01 +080057 else:
58 if (size > 0):
59 print("customer section:%s, size:%d" % (section, size))
60 self.customize += size
xiaohu.huange6c31672022-12-05 10:10:42 +080061 def add_xcc_section(self, section, size):
xiaohu.huangfc139972024-01-23 10:36:50 +080062 if current_section is None:
63 return;
xiaohu.huange6c31672022-12-05 10:10:42 +080064 if section.startswith('.comment'):
65 return
66 if section.startswith('.debug'):
67 return
68 if section.startswith('.xt.prop')or section.startswith('.xt.lit'):
69 return
70 if section.startswith('.text') or section.endswith('.text') \
71 or section.startswith('.literal') or section.endswith('.literal') \
72 or section.startswith('.rodata') or section.endswith('.rodata'):
73 self.text += size
74 elif section.startswith('.rela.dyn'):
75 self.rela_text += size
76 elif section.startswith('.bss') or section.startswith('.common') or section.startswith('.sbss'):
77 self.bss += size
78 elif section.startswith('.data') or section.endswith('.data'):
79 self.data += size
80 elif section.startswith('.heap'):
81 self.heap += size
82 self.bss += size
83 elif section.startswith('.stack'):
84 self.stack += size
85 self.bss += size
86 else:
87 if (size > 0):
88 print("customer section:%s, size:%d" % (section, size))
89 self.customize += size
xiaohu.huangffae1712022-11-01 18:04:01 +080090
91size_by_source = {}
xiaohu.huangffae1712022-11-01 18:04:01 +080092with open(args.map_file) as f:
xiaohu.huang29fd84c2022-12-19 15:27:00 +080093 if os.getenv('COMPILER') == "xcc":
xiaohu.huange6c31672022-12-05 10:10:42 +080094 arch_toolchain = "XCC"
95 toolchain_keyword = "xtensa-elf"
96 is_xtensa = 1
97 else:
98 arch_toolchain = "GCC"
99 toolchain_keyword = "toolchains"
100 is_xtensa = 0
101 print("%s toolchain map analyzer" % arch_toolchain)
102
xiaohu.huangffae1712022-11-01 18:04:01 +0800103 lines = iter(f)
104 for line in lines:
105 if line.strip() == "Linker script and memory map":
106 break
107
108 current_section = None
109 split_line = None
110 last_addr = 0
111 last_size = 0
112 for line in lines:
113 line = line.strip('\n')
114 if split_line:
115 # Glue a line that was split in two back together
116 if line.startswith(' ' * 16):
117 line = split_line + line
118 else: # Shouldn't happen
119 print("Warning: discarding line ", split_line)
120 split_line = None
121
122 if ('size before relaxing' in line):
123 continue
124 if line.startswith((".", " .", " *fill*")):
125 pieces = line.split(None, 3) # Don't split paths containing spaces
xiaohu.huang1f337742023-04-20 17:06:31 +0800126 pieces_num = len(pieces)
xiaohu.huangffae1712022-11-01 18:04:01 +0800127
128 if line.startswith("."):
129 # Note: this line might be wrapped, with the size of the section
130 # on the next line, but we ignore the size anyway and will ignore that line
131 current_section = pieces[0]
xiaohu.huange6c31672022-12-05 10:10:42 +0800132 # XCC text section format
xiaohu.huang1f337742023-04-20 17:06:31 +0800133 if (pieces_num == 4):
xiaohu.huange6c31672022-12-05 10:10:42 +0800134 source = pieces[-1]
xiaohu.huang1f337742023-04-20 17:06:31 +0800135 elif pieces_num == 1 and len(line) > 14:
xiaohu.huangffae1712022-11-01 18:04:01 +0800136 # ld splits the rest of this line onto the next if the section name is too long
137 split_line = line
xiaohu.huang1f337742023-04-20 17:06:31 +0800138 elif pieces_num >= 3 and "=" not in pieces and "before" not in pieces:
xiaohu.huangffae1712022-11-01 18:04:01 +0800139 if pieces[0] == "*fill*":
140 # fill use the last source to store the fill align data
141 #source = pieces[0]
142 size = int(pieces[-1], 16)
143 if (pieces[-2] == last_addr):
144 # sub the merged size from the same address for fill data
145 size = size - last_size
146 else:
147 last_size = size
148 last_addr = pieces[-2]
149 else:
150 source = pieces[-1]
151 size = int(pieces[-2], 16)
152 if (pieces[-3] == last_addr):
153 # sub the merged size from the same address for text data
154 size = size - last_size
155 else:
156 last_size = size
157 last_addr = pieces[-3]
158
159 if args.combine:
160 if '.a(' in source:
161 # path/to/archive.a(object.o)
162 source = source[:source.index('.a(') + 2]
163 elif '.dir' in source:
164 source = source[:source.find(".dir")]
165 elif source.endswith('.o'):
xiaohu.huange6c31672022-12-05 10:10:42 +0800166 if toolchain_keyword in source:
xiaohu.huangffae1712022-11-01 18:04:01 +0800167 source = 'toolchain_obj'
168 else:
169 source = os.path.basename(source)
170
171 if source not in size_by_source:
172 size_by_source[source] = SectionSize()
xiaohu.huange6c31672022-12-05 10:10:42 +0800173 if is_xtensa == 1:
174 size_by_source[source].add_xcc_section(current_section, size)
175 else:
176 size_by_source[source].add_gcc_section(current_section, size)
xiaohu.huangffae1712022-11-01 18:04:01 +0800177
178# Print out summary
179sources = list(size_by_source.keys())
180sources.sort(key = lambda x: size_by_source[x].total())
xiaohu.huang1f337742023-04-20 17:06:31 +0800181sumrom = sumram = sumcode = sumdata = sumbss = sumcustomize = 0
xiaohu.huangffae1712022-11-01 18:04:01 +0800182
183print('---------------------------------------------------------------------------------------------------')
184col_format = "%-20s\t%-12s\t%-12s\t%-7s\t%-12s\t%-12s\t%-7s"
185print(col_format % ("module file", "ROM(text+data)", "RAM(data+bss)", ".text", ".data", ".bss", "customize"))
186for source in sources:
187 size = size_by_source[source]
188 sumcode += size.text
189 sumdata += size.data
190 sumbss += size.bss
191 sumrom += size.rom()
192 sumram += size.ram()
xiaohu.huangffae1712022-11-01 18:04:01 +0800193 sumcustomize += size.customize
194 print(col_format % (os.path.basename(source), size.rom(), size.ram(), size.text, size.data, size.bss, size.customize))
195
196print('---------------------------------------------------------------------------------------------------')
197col_format = "%-5s\t%-12s\t%-12s\t%-7s\t%-12s\t%-12s\t%-7s\t%-7s\t%-7s"
xiaohu.huang1f337742023-04-20 17:06:31 +0800198sys_mem_usage = SectionSize.system_stack + SectionSize.system_heap
xiaohu.huangffae1712022-11-01 18:04:01 +0800199print(col_format % (" ", "ROM(text+data)", "RAM(data+bss)", ".text", ".data", ".bss", "cust", "stack", "heap" ))
xiaohu.huang1f337742023-04-20 17:06:31 +0800200print(col_format % ("total", sumrom, sumram + sys_mem_usage, sumcode, sumdata, sumbss + sys_mem_usage, sumcustomize, SectionSize.system_stack, SectionSize.system_heap))
xiaohu.huangffae1712022-11-01 18:04:01 +0800201print('---------------------------------------------------------------------------------------------------')