Jianliang Shen | 9b4ba11 | 2022-01-19 14:57:04 +0800 | [diff] [blame] | 1 | # ------------------------------------------------------------------------------ |
| 2 | # Copyright (c) 2021-2022, Arm Limited. All rights reserved. |
Jianliang Shen | abf0041 | 2021-11-12 10:58:52 +0800 | [diff] [blame] | 3 | # |
| 4 | # SPDX-License-Identifier: BSD-3-Clause |
| 5 | # |
Jianliang Shen | 9b4ba11 | 2022-01-19 14:57:04 +0800 | [diff] [blame] | 6 | # ------------------------------------------------------------------------------ |
Jianliang Shen | abf0041 | 2021-11-12 10:58:52 +0800 | [diff] [blame] | 7 | |
Jianliang Shen | abf0041 | 2021-11-12 10:58:52 +0800 | [diff] [blame] | 8 | import argparse |
| 9 | import os |
Jianliang Shen | 9b4ba11 | 2022-01-19 14:57:04 +0800 | [diff] [blame] | 10 | import sys |
Jianliang Shen | 28cce57 | 2022-05-02 21:44:03 +0800 | [diff] [blame] | 11 | import glob |
Jianliang Shen | 9b4ba11 | 2022-01-19 14:57:04 +0800 | [diff] [blame] | 12 | sys.path.append("src") |
| 13 | from ui import UI |
| 14 | from sq import SQ |
Jianliang Shen | abf0041 | 2021-11-12 10:58:52 +0800 | [diff] [blame] | 15 | |
Jianliang Shen | 28cce57 | 2022-05-02 21:44:03 +0800 | [diff] [blame] | 16 | none_databse = "Cannot find database {}! Please use this command to create \ |
| 17 | databse:\n\n\tpython3 code_size_analyze.py --map <map file path> \ |
| 18 | --gnuarm/--armcc --db {}\n" |
| 19 | |
| 20 | def reverse_terminal_text(items): |
| 21 | line1 = "─" * 128 |
| 22 | tmp, ret = [], [] |
| 23 | for x in items: |
| 24 | if x == line1: |
| 25 | ret.append(tmp) |
| 26 | tmp = [] |
| 27 | tmp.append(x) |
| 28 | items = [] |
| 29 | for i in range(len(ret) - 1, -1, -1): |
| 30 | items.extend(ret[i]) |
| 31 | items.append(line1) |
| 32 | return items |
Jianliang Shen | abf0041 | 2021-11-12 10:58:52 +0800 | [diff] [blame] | 33 | |
| 34 | def main(args): |
Jianliang Shen | 28cce57 | 2022-05-02 21:44:03 +0800 | [diff] [blame] | 35 | map_file, db_file = "", "" |
| 36 | if args.file_input.find(".map") >= 0: |
| 37 | map_file = args.file_input |
| 38 | else: |
| 39 | db_file = args.file_input |
Jianliang Shen | 9b4ba11 | 2022-01-19 14:57:04 +0800 | [diff] [blame] | 40 | """ |
| 41 | Class 'sq' is to create a sqlite3 database from map file of compiler. |
| 42 | """ |
Jianliang Shen | 28cce57 | 2022-05-02 21:44:03 +0800 | [diff] [blame] | 43 | if map_file: |
| 44 | if not args.gnuarm_compiler and not args.armclang_compiler: |
| 45 | print("Error: Need --gnuarm or --armcc to create database") |
| 46 | exit(0) |
| 47 | if os.path.exists(args.db_name): |
| 48 | for infile in glob.glob(os.path.join(os.getcwd(), args.db_name)): |
| 49 | os.remove(infile) |
Jianliang Shen | 9b4ba11 | 2022-01-19 14:57:04 +0800 | [diff] [blame] | 50 | sq = SQ() |
| 51 | sq.gnuarm = True if args.gnuarm_compiler else False |
| 52 | sq.armcc = True if args.armclang_compiler else False |
Jianliang Shen | 28cce57 | 2022-05-02 21:44:03 +0800 | [diff] [blame] | 53 | sq.map_file = map_file |
| 54 | sq.db_name = args.db_name |
Jianliang Shen | 9b4ba11 | 2022-01-19 14:57:04 +0800 | [diff] [blame] | 55 | sq.update() |
Jianliang Shen | abf0041 | 2021-11-12 10:58:52 +0800 | [diff] [blame] | 56 | |
Jianliang Shen | 28cce57 | 2022-05-02 21:44:03 +0800 | [diff] [blame] | 57 | if (db_file and os.path.exists(db_file)) or (map_file and os.path.exists(args.db_name)): |
Jianliang Shen | 9b4ba11 | 2022-01-19 14:57:04 +0800 | [diff] [blame] | 58 | """ |
| 59 | Class 'ui' is to show the ui in terminal or export plaintext. |
| 60 | """ |
| 61 | ui = UI() |
| 62 | ui.gnuarm = True if args.gnuarm_compiler else False |
| 63 | ui.armcc = True if args.armclang_compiler else False |
Jianliang Shen | 28cce57 | 2022-05-02 21:44:03 +0800 | [diff] [blame] | 64 | if db_file: |
| 65 | ui.db_file = db_file |
| 66 | if map_file: |
| 67 | ui.db_file = args.db_name |
| 68 | ui.open_db() |
| 69 | if args.sort_by_size: |
| 70 | ui.sort = "size" |
| 71 | if args.sort_by_name: |
| 72 | ui.sort = "name" |
| 73 | if args.sort_by_obj: |
| 74 | ui.sort = "obj_file" |
| 75 | if args.sort_by_lib: |
| 76 | ui.sort = "lib_file" |
| 77 | if args.sort_by_sec: |
| 78 | ui.sort = "section" |
| 79 | |
| 80 | if args.desc: |
| 81 | ui.order = "DESC" |
| 82 | if args.asc: |
| 83 | ui.order = "ASC" |
| 84 | |
Jianliang Shen | 9b4ba11 | 2022-01-19 14:57:04 +0800 | [diff] [blame] | 85 | if args.ui_show: |
Jianliang Shen | 28cce57 | 2022-05-02 21:44:03 +0800 | [diff] [blame] | 86 | if args.sort_by_name or args.sort_by_obj or args.sort_by_lib or args.sort_by_sec: |
| 87 | print("UI mode cannot support sort. Use it in terminal mode.") |
| 88 | exit(0) |
Jianliang Shen | abf0041 | 2021-11-12 10:58:52 +0800 | [diff] [blame] | 89 | ui.run() |
Jianliang Shen | abf0041 | 2021-11-12 10:58:52 +0800 | [diff] [blame] | 90 | |
Jianliang Shen | 28cce57 | 2022-05-02 21:44:03 +0800 | [diff] [blame] | 91 | if args.all: |
| 92 | ui.draw_summary_page() |
Jianliang Shen | abf0041 | 2021-11-12 10:58:52 +0800 | [diff] [blame] | 93 | |
Jianliang Shen | 28cce57 | 2022-05-02 21:44:03 +0800 | [diff] [blame] | 94 | if args.list_function: |
| 95 | ui.draw_function_page("") |
Jianliang Shen | abf0041 | 2021-11-12 10:58:52 +0800 | [diff] [blame] | 96 | |
Jianliang Shen | 28cce57 | 2022-05-02 21:44:03 +0800 | [diff] [blame] | 97 | if args.function_name: |
| 98 | ui.draw_function_page(args.function_name) |
Jianliang Shen | abf0041 | 2021-11-12 10:58:52 +0800 | [diff] [blame] | 99 | |
Jianliang Shen | 28cce57 | 2022-05-02 21:44:03 +0800 | [diff] [blame] | 100 | if args.dump_function_name: |
| 101 | ui.function_name = args.dump_function_name |
| 102 | ui.draw_function_detail_page() |
Jianliang Shen | abf0041 | 2021-11-12 10:58:52 +0800 | [diff] [blame] | 103 | |
Jianliang Shen | 28cce57 | 2022-05-02 21:44:03 +0800 | [diff] [blame] | 104 | if args.list_data: |
| 105 | ui.draw_data_page("") |
Jianliang Shen | abf0041 | 2021-11-12 10:58:52 +0800 | [diff] [blame] | 106 | |
Jianliang Shen | 28cce57 | 2022-05-02 21:44:03 +0800 | [diff] [blame] | 107 | if args.data_name: |
| 108 | ui.draw_data_page(args.data_name) |
Jianliang Shen | abf0041 | 2021-11-12 10:58:52 +0800 | [diff] [blame] | 109 | |
Jianliang Shen | 28cce57 | 2022-05-02 21:44:03 +0800 | [diff] [blame] | 110 | if args.dump_data_name: |
| 111 | ui.data_name = args.dump_data_name |
| 112 | ui.draw_data_detail_page() |
Jianliang Shen | abf0041 | 2021-11-12 10:58:52 +0800 | [diff] [blame] | 113 | |
Jianliang Shen | 28cce57 | 2022-05-02 21:44:03 +0800 | [diff] [blame] | 114 | if args.list_obj: |
| 115 | if args.sort_by_obj: |
| 116 | ui.sort = "name" |
| 117 | if args.sort_by_sec: |
| 118 | print("Object files cannot sort by this option") |
| 119 | exit(0) |
| 120 | ui.draw_obj_page() |
Jianliang Shen | abf0041 | 2021-11-12 10:58:52 +0800 | [diff] [blame] | 121 | |
Jianliang Shen | 28cce57 | 2022-05-02 21:44:03 +0800 | [diff] [blame] | 122 | if args.obj_name: |
| 123 | ui.obj_file = args.obj_name |
| 124 | ui.draw_obj_detail_page() |
| 125 | ui.items = reverse_terminal_text(ui.items) |
Jianliang Shen | abf0041 | 2021-11-12 10:58:52 +0800 | [diff] [blame] | 126 | |
Jianliang Shen | 28cce57 | 2022-05-02 21:44:03 +0800 | [diff] [blame] | 127 | if args.list_library: |
| 128 | if args.sort_by_lib: |
| 129 | ui.sort = "name" |
| 130 | if args.sort_by_obj or args.sort_by_sec: |
| 131 | print("Libraries cannot sort by this option") |
| 132 | exit(0) |
| 133 | ui.draw_library_page() |
Jianliang Shen | abf0041 | 2021-11-12 10:58:52 +0800 | [diff] [blame] | 134 | |
Jianliang Shen | 28cce57 | 2022-05-02 21:44:03 +0800 | [diff] [blame] | 135 | if args.library_name: |
| 136 | if args.sort_by_sec or args.sort_by_obj: |
| 137 | print("Library dump cannot sort by this option") |
| 138 | exit(0) |
| 139 | ui.library_name = args.library_name |
| 140 | ui.draw_library_detail_page() |
| 141 | ui.items = reverse_terminal_text(ui.items) |
Jianliang Shen | abf0041 | 2021-11-12 10:58:52 +0800 | [diff] [blame] | 142 | |
Jianliang Shen | 28cce57 | 2022-05-02 21:44:03 +0800 | [diff] [blame] | 143 | if args.list_section: |
| 144 | if args.sort_by_sec: |
| 145 | ui.sort = "name" |
| 146 | if args.sort_by_lib or args.sort_by_obj: |
| 147 | print("Sections cannot sort by this option") |
| 148 | exit(0) |
| 149 | ui.draw_section_page() |
Jianliang Shen | abf0041 | 2021-11-12 10:58:52 +0800 | [diff] [blame] | 150 | |
Jianliang Shen | 28cce57 | 2022-05-02 21:44:03 +0800 | [diff] [blame] | 151 | if args.section_name: |
| 152 | if args.sort_by_name or args.sort_by_obj or args.sort_by_lib or args.sort_by_sec: |
| 153 | print("Section dump cannot support sort.") |
| 154 | exit(0) |
| 155 | ui.section_name = args.section_name |
| 156 | ui.draw_section_lib() |
| 157 | ui.items = reverse_terminal_text(ui.items) |
| 158 | |
| 159 | if "─" * 128 not in ui.items and "-" * 128 not in ui.items and ui.items: |
| 160 | max_len = 0 |
| 161 | for x in ui.items: |
| 162 | max_len = max(max_len, len(x)) |
| 163 | ui.items.insert(1, "-" * max_len) |
| 164 | ui.items.insert(0, "─" * max_len) |
| 165 | ui.items.append("─" * max_len) |
| 166 | |
| 167 | if ui.items and not args.ui_show: |
| 168 | for s in ui.items: |
| 169 | print(s) |
| 170 | |
Jianliang Shen | 9b4ba11 | 2022-01-19 14:57:04 +0800 | [diff] [blame] | 171 | else: |
Jianliang Shen | 28cce57 | 2022-05-02 21:44:03 +0800 | [diff] [blame] | 172 | print(none_databse.format(db_file, db_file)) |
Jianliang Shen | abf0041 | 2021-11-12 10:58:52 +0800 | [diff] [blame] | 173 | |
| 174 | def parse_args(): |
| 175 | """ |
Jianliang Shen | 9b4ba11 | 2022-01-19 14:57:04 +0800 | [diff] [blame] | 176 | List the arguments for program. |
Jianliang Shen | abf0041 | 2021-11-12 10:58:52 +0800 | [diff] [blame] | 177 | """ |
Jianliang Shen | abf0041 | 2021-11-12 10:58:52 +0800 | [diff] [blame] | 178 | parser = argparse.ArgumentParser() |
| 179 | |
Jianliang Shen | 28cce57 | 2022-05-02 21:44:03 +0800 | [diff] [blame] | 180 | compiler_group = parser.add_mutually_exclusive_group() |
| 181 | compiler_group.add_argument('--gnuarm', |
| 182 | dest='gnuarm_compiler', |
| 183 | action='store_true', |
| 184 | help='GNUARM model') |
| 185 | compiler_group.add_argument('--armcc', |
| 186 | dest='armclang_compiler', |
| 187 | action='store_true', |
| 188 | help='ARMCLANG model') |
| 189 | |
| 190 | parser.add_argument('file_input', help='map or database file') |
| 191 | parser.add_argument('--db-name', |
| 192 | dest='db_name', |
| 193 | metavar='<data.db>', |
| 194 | default='data.db', |
| 195 | help='database name to save') |
| 196 | |
| 197 | terminal_opt = parser.add_mutually_exclusive_group() |
| 198 | terminal_opt.add_argument('-u', '--ui', |
| 199 | dest='ui_show', |
| 200 | action='store_true', |
| 201 | help='start UI to analyze') |
| 202 | terminal_opt.add_argument('-S', '--Summary', |
| 203 | dest='all', |
| 204 | action='store_true', |
| 205 | help='show summary message') |
| 206 | terminal_opt.add_argument('-s', '--list-section', |
| 207 | dest='list_section', |
| 208 | action='store_true', |
| 209 | help='list section') |
| 210 | terminal_opt.add_argument('-l', '--list-library', |
| 211 | dest='list_library', |
| 212 | action='store_true', |
| 213 | help='list library') |
| 214 | terminal_opt.add_argument('-o', '--list-obj', |
| 215 | dest='list_obj', |
| 216 | action='store_true', |
| 217 | help='list object file') |
| 218 | terminal_opt.add_argument('-f', '--list-function', |
| 219 | dest='list_function', |
| 220 | action='store_true', |
| 221 | help='list function') |
| 222 | terminal_opt.add_argument('-d', '--list-data', |
| 223 | dest='list_data', |
| 224 | action='store_true', |
| 225 | help='list data') |
| 226 | terminal_opt.add_argument('--dump-sec', |
| 227 | dest='section_name', |
| 228 | metavar='<sec>', |
| 229 | help='dump section') |
| 230 | terminal_opt.add_argument('--dump-lib', |
| 231 | dest='library_name', |
| 232 | metavar='<lib>', |
| 233 | help='dump library') |
| 234 | terminal_opt.add_argument('--dump-obj', |
| 235 | dest='obj_name', |
| 236 | metavar='<obj>', |
| 237 | help='dump object file') |
| 238 | terminal_opt.add_argument('--dump-func', |
| 239 | dest='dump_function_name', |
| 240 | metavar='<func>', |
| 241 | help='dump function') |
| 242 | terminal_opt.add_argument('--dump-data', |
| 243 | dest='dump_data_name', |
| 244 | metavar='<data>', |
| 245 | help='dump data') |
| 246 | terminal_opt.add_argument('--search-func', |
| 247 | dest='function_name', |
| 248 | metavar='<func>', |
| 249 | help='search function') |
| 250 | terminal_opt.add_argument('--search-data', |
| 251 | dest='data_name', |
| 252 | metavar='<data>', |
| 253 | help='search data') |
| 254 | |
| 255 | sort_opt = parser.add_mutually_exclusive_group() |
| 256 | sort_opt.add_argument('--sort-by-size', |
| 257 | dest='sort_by_size', |
| 258 | action='store_true', |
| 259 | default=True, |
| 260 | help='list by size order') |
| 261 | sort_opt.add_argument('--sort-by-name', |
| 262 | dest='sort_by_name', |
| 263 | action='store_true', |
| 264 | default=False, |
| 265 | help='list by name order') |
| 266 | sort_opt.add_argument('--sort-by-obj', |
| 267 | dest='sort_by_obj', |
| 268 | action='store_true', |
| 269 | default=False, |
| 270 | help='list by object file name order') |
| 271 | sort_opt.add_argument('--sort-by-lib', |
| 272 | dest='sort_by_lib', |
| 273 | action='store_true', |
| 274 | default=False, |
| 275 | help='list by library file name order') |
| 276 | sort_opt.add_argument('--sort-by-sec', |
| 277 | dest='sort_by_sec', |
| 278 | action='store_true', |
| 279 | default=False, |
| 280 | help='list by section name order') |
| 281 | |
| 282 | sort_ord = parser.add_mutually_exclusive_group() |
| 283 | sort_ord.add_argument('--desc', |
| 284 | dest='desc', |
| 285 | action='store_true', |
| 286 | default=True, |
| 287 | help='sort with desc order') |
| 288 | sort_ord.add_argument('--asc', |
| 289 | dest='asc', |
| 290 | action='store_true', |
| 291 | default=False, |
| 292 | help='sort with asc order') |
| 293 | |
Jianliang Shen | abf0041 | 2021-11-12 10:58:52 +0800 | [diff] [blame] | 294 | args = parser.parse_args() |
| 295 | return args |
| 296 | |
Jianliang Shen | abf0041 | 2021-11-12 10:58:52 +0800 | [diff] [blame] | 297 | if __name__ == '__main__': |
| 298 | main(parse_args()) |
| 299 | exit(0) |