15f9996aaSopenharmony_ci#!/usr/bin/env python3 25f9996aaSopenharmony_ci# -*- coding: utf-8 -*- 35f9996aaSopenharmony_ci 45f9996aaSopenharmony_ci# 55f9996aaSopenharmony_ci# Copyright (c) 2022 Huawei Device Co., Ltd. 65f9996aaSopenharmony_ci# Licensed under the Apache License, Version 2.0 (the "License"); 75f9996aaSopenharmony_ci# you may not use this file except in compliance with the License. 85f9996aaSopenharmony_ci# You may obtain a copy of the License at 95f9996aaSopenharmony_ci# 105f9996aaSopenharmony_ci# http://www.apache.org/licenses/LICENSE-2.0 115f9996aaSopenharmony_ci# 125f9996aaSopenharmony_ci# Unless required by applicable law or agreed to in writing, software 135f9996aaSopenharmony_ci# distributed under the License is distributed on an "AS IS" BASIS, 145f9996aaSopenharmony_ci# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 155f9996aaSopenharmony_ci# See the License for the specific language governing permissions and 165f9996aaSopenharmony_ci# limitations under the License. 175f9996aaSopenharmony_ci# 185f9996aaSopenharmony_ci 195f9996aaSopenharmony_ciimport sys 205f9996aaSopenharmony_ciimport argparse 215f9996aaSopenharmony_ciimport os 225f9996aaSopenharmony_ciimport platform 235f9996aaSopenharmony_ciimport subprocess 245f9996aaSopenharmony_ci 255f9996aaSopenharmony_ci 265f9996aaSopenharmony_cidef gen_symbols(tmp_file, sort_lines, symbols_path): 275f9996aaSopenharmony_ci with os.fdopen(os.open(tmp_file, os.O_RDWR | os.O_CREAT), 'w', encoding='utf-8') as output_file: 285f9996aaSopenharmony_ci for item in sort_lines: 295f9996aaSopenharmony_ci output_file.write('{}\n'.format(item)) 305f9996aaSopenharmony_ci 315f9996aaSopenharmony_ci with os.fdopen(os.open(symbols_path, os.O_RDWR | os.O_CREAT), 'w', encoding='utf-8') as output_file: 325f9996aaSopenharmony_ci cmd = 'sort {}'.format(tmp_file) 335f9996aaSopenharmony_ci subprocess.run(cmd.split(), stdout=output_file) 345f9996aaSopenharmony_ci 355f9996aaSopenharmony_ci 365f9996aaSopenharmony_cidef create_mini_debug_info(binary_path, stripped_binary_path, root_path, clang_base_dir): 375f9996aaSopenharmony_ci # temporary file path 385f9996aaSopenharmony_ci dynsyms_path = stripped_binary_path + ".dynsyms" 395f9996aaSopenharmony_ci funcsysms_path = stripped_binary_path + ".funcsyms" 405f9996aaSopenharmony_ci keep_path = stripped_binary_path + ".keep" 415f9996aaSopenharmony_ci debug_path = stripped_binary_path + ".debug" 425f9996aaSopenharmony_ci mini_debug_path = stripped_binary_path + ".minidebug" 435f9996aaSopenharmony_ci 445f9996aaSopenharmony_ci # llvm tools path 455f9996aaSopenharmony_ci host_platform = platform.uname().system.lower() 465f9996aaSopenharmony_ci host_cpu = platform.uname().machine.lower() 475f9996aaSopenharmony_ci llvm_dir_path = os.path.join( 485f9996aaSopenharmony_ci clang_base_dir, host_platform + '-' + host_cpu, 'llvm/bin') 495f9996aaSopenharmony_ci if not os.path.exists(llvm_dir_path): 505f9996aaSopenharmony_ci llvm_dir_path = os.path.join(root_path, 'out/llvm-install/bin') 515f9996aaSopenharmony_ci llvm_nm_path = os.path.join(llvm_dir_path, "llvm-nm") 525f9996aaSopenharmony_ci llvm_objcopy_path = os.path.join(llvm_dir_path, "llvm-objcopy") 535f9996aaSopenharmony_ci 545f9996aaSopenharmony_ci cmd_list = [] 555f9996aaSopenharmony_ci 565f9996aaSopenharmony_ci gen_symbols_cmd = llvm_nm_path + " -D " + binary_path + " --format=posix --defined-only" 575f9996aaSopenharmony_ci gen_func_symbols_cmd = llvm_nm_path + " " + binary_path + " --format=posix --defined-only" 585f9996aaSopenharmony_ci gen_keep_symbols_cmd = "comm -13 " + dynsyms_path + " " + funcsysms_path 595f9996aaSopenharmony_ci gen_keep_debug_cmd = llvm_objcopy_path + \ 605f9996aaSopenharmony_ci " --only-keep-debug " + binary_path + " " + debug_path 615f9996aaSopenharmony_ci gen_mini_debug_cmd = llvm_objcopy_path + " -S --remove-section .gdb_index --remove-section .comment --keep-symbols=" + \ 625f9996aaSopenharmony_ci keep_path + " " + debug_path + " " + mini_debug_path 635f9996aaSopenharmony_ci compress_debuginfo = "xz " + mini_debug_path 645f9996aaSopenharmony_ci gen_stripped_binary = llvm_objcopy_path + " --add-section .gnu_debugdata=" + \ 655f9996aaSopenharmony_ci mini_debug_path + ".xz " + stripped_binary_path 665f9996aaSopenharmony_ci 675f9996aaSopenharmony_ci 685f9996aaSopenharmony_ci tmp_file1 = '{}.tmp1'.format(dynsyms_path) 695f9996aaSopenharmony_ci tmp_file2 = '{}.tmp2'.format(dynsyms_path) 705f9996aaSopenharmony_ci with os.fdopen(os.open(tmp_file1, os.O_RDWR | os.O_CREAT), 'w', encoding='utf-8') as output_file: 715f9996aaSopenharmony_ci subprocess.run(gen_symbols_cmd.split(), stdout=output_file) 725f9996aaSopenharmony_ci 735f9996aaSopenharmony_ci with os.fdopen(os.open(tmp_file1, os.O_RDWR | os.O_CREAT), 'r', encoding='utf-8') as output_file: 745f9996aaSopenharmony_ci lines = output_file.readlines() 755f9996aaSopenharmony_ci sort_lines = [] 765f9996aaSopenharmony_ci for line in lines: 775f9996aaSopenharmony_ci columns = line.strip().split() 785f9996aaSopenharmony_ci if columns: 795f9996aaSopenharmony_ci sort_lines.append(columns[0]) 805f9996aaSopenharmony_ci 815f9996aaSopenharmony_ci gen_symbols(tmp_file2, sort_lines, dynsyms_path) 825f9996aaSopenharmony_ci os.remove(tmp_file1) 835f9996aaSopenharmony_ci os.remove(tmp_file2) 845f9996aaSopenharmony_ci 855f9996aaSopenharmony_ci 865f9996aaSopenharmony_ci tmp_file1 = '{}.tmp1'.format(funcsysms_path) 875f9996aaSopenharmony_ci tmp_file2 = '{}.tmp2'.format(funcsysms_path) 885f9996aaSopenharmony_ci with os.fdopen(os.open(tmp_file1, os.O_RDWR | os.O_CREAT), 'w', encoding='utf-8') as output_file: 895f9996aaSopenharmony_ci subprocess.run(gen_func_symbols_cmd.split(), stdout=output_file) 905f9996aaSopenharmony_ci 915f9996aaSopenharmony_ci with os.fdopen(os.open(tmp_file1, os.O_RDWR | os.O_CREAT), 'r', encoding='utf-8') as output_file: 925f9996aaSopenharmony_ci lines = output_file.readlines() 935f9996aaSopenharmony_ci sort_lines = [] 945f9996aaSopenharmony_ci for line in lines: 955f9996aaSopenharmony_ci columns = line.strip().split() 965f9996aaSopenharmony_ci if len(columns) > 2 and ('t' in columns[1] or 'T' in columns[1] or 'd' in columns[1]): 975f9996aaSopenharmony_ci sort_lines.append(columns[0]) 985f9996aaSopenharmony_ci 995f9996aaSopenharmony_ci gen_symbols(tmp_file2, sort_lines, funcsysms_path) 1005f9996aaSopenharmony_ci os.remove(tmp_file1) 1015f9996aaSopenharmony_ci os.remove(tmp_file2) 1025f9996aaSopenharmony_ci 1035f9996aaSopenharmony_ci 1045f9996aaSopenharmony_ci with os.fdopen(os.open(keep_path, os.O_RDWR | os.O_CREAT), 'w', encoding='utf-8') as output_file: 1055f9996aaSopenharmony_ci subprocess.run(gen_keep_symbols_cmd.split(), stdout=output_file) 1065f9996aaSopenharmony_ci 1075f9996aaSopenharmony_ci 1085f9996aaSopenharmony_ci cmd_list.append(gen_keep_debug_cmd) 1095f9996aaSopenharmony_ci cmd_list.append(gen_mini_debug_cmd) 1105f9996aaSopenharmony_ci cmd_list.append(compress_debuginfo) 1115f9996aaSopenharmony_ci cmd_list.append(gen_stripped_binary) 1125f9996aaSopenharmony_ci 1135f9996aaSopenharmony_ci # execute each cmd to generate temporary file 1145f9996aaSopenharmony_ci # which .gnu_debugdata section depends on 1155f9996aaSopenharmony_ci for cmd in cmd_list: 1165f9996aaSopenharmony_ci subprocess.call(cmd.split(), shell=False) 1175f9996aaSopenharmony_ci 1185f9996aaSopenharmony_ci # remove temporary file 1195f9996aaSopenharmony_ci os.remove(dynsyms_path) 1205f9996aaSopenharmony_ci os.remove(funcsysms_path) 1215f9996aaSopenharmony_ci os.remove(keep_path) 1225f9996aaSopenharmony_ci os.remove(debug_path) 1235f9996aaSopenharmony_ci os.remove(mini_debug_path + ".xz") 1245f9996aaSopenharmony_ci 1255f9996aaSopenharmony_ci 1265f9996aaSopenharmony_cidef main(): 1275f9996aaSopenharmony_ci parser = argparse.ArgumentParser(description=__doc__) 1285f9996aaSopenharmony_ci parser.add_argument("--unstripped-path", 1295f9996aaSopenharmony_ci help="unstripped binary path") 1305f9996aaSopenharmony_ci parser.add_argument("--stripped-path", 1315f9996aaSopenharmony_ci help="stripped binary path") 1325f9996aaSopenharmony_ci parser.add_argument("--root-path", 1335f9996aaSopenharmony_ci help="root path is used to search llvm toolchain") 1345f9996aaSopenharmony_ci parser.add_argument("--clang-base-dir", help="") 1355f9996aaSopenharmony_ci args = parser.parse_args() 1365f9996aaSopenharmony_ci 1375f9996aaSopenharmony_ci create_mini_debug_info(args.unstripped_path, 1385f9996aaSopenharmony_ci args.stripped_path, args.root_path, args.clang_base_dir) 1395f9996aaSopenharmony_ci 1405f9996aaSopenharmony_ci 1415f9996aaSopenharmony_ciif __name__ == "__main__": 1425f9996aaSopenharmony_ci sys.exit(main()) 143