18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright (C) 2017 Josh Poimboeuf <jpoimboe@redhat.com> 48c2ecf20Sopenharmony_ci */ 58c2ecf20Sopenharmony_ci 68c2ecf20Sopenharmony_ci/* 78c2ecf20Sopenharmony_ci * objtool orc: 88c2ecf20Sopenharmony_ci * 98c2ecf20Sopenharmony_ci * This command analyzes a .o file and adds .orc_unwind and .orc_unwind_ip 108c2ecf20Sopenharmony_ci * sections to it, which is used by the in-kernel ORC unwinder. 118c2ecf20Sopenharmony_ci * 128c2ecf20Sopenharmony_ci * This command is a superset of "objtool check". 138c2ecf20Sopenharmony_ci */ 148c2ecf20Sopenharmony_ci 158c2ecf20Sopenharmony_ci#include <string.h> 168c2ecf20Sopenharmony_ci#include "builtin.h" 178c2ecf20Sopenharmony_ci#include "objtool.h" 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_cistatic const char *orc_usage[] = { 208c2ecf20Sopenharmony_ci "objtool orc generate [<options>] file.o", 218c2ecf20Sopenharmony_ci "objtool orc dump file.o", 228c2ecf20Sopenharmony_ci NULL, 238c2ecf20Sopenharmony_ci}; 248c2ecf20Sopenharmony_ci 258c2ecf20Sopenharmony_ciint cmd_orc(int argc, const char **argv) 268c2ecf20Sopenharmony_ci{ 278c2ecf20Sopenharmony_ci const char *objname; 288c2ecf20Sopenharmony_ci 298c2ecf20Sopenharmony_ci argc--; argv++; 308c2ecf20Sopenharmony_ci if (argc <= 0) 318c2ecf20Sopenharmony_ci usage_with_options(orc_usage, check_options); 328c2ecf20Sopenharmony_ci 338c2ecf20Sopenharmony_ci if (!strncmp(argv[0], "gen", 3)) { 348c2ecf20Sopenharmony_ci struct objtool_file *file; 358c2ecf20Sopenharmony_ci int ret; 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_ci argc = parse_options(argc, argv, check_options, orc_usage, 0); 388c2ecf20Sopenharmony_ci if (argc != 1) 398c2ecf20Sopenharmony_ci usage_with_options(orc_usage, check_options); 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_ci objname = argv[0]; 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_ci file = objtool_open_read(objname); 448c2ecf20Sopenharmony_ci if (!file) 458c2ecf20Sopenharmony_ci return 1; 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_ci ret = check(file); 488c2ecf20Sopenharmony_ci if (ret) 498c2ecf20Sopenharmony_ci return ret; 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_ci if (list_empty(&file->insn_list)) 528c2ecf20Sopenharmony_ci return 0; 538c2ecf20Sopenharmony_ci 548c2ecf20Sopenharmony_ci ret = orc_create(file); 558c2ecf20Sopenharmony_ci if (ret) 568c2ecf20Sopenharmony_ci return ret; 578c2ecf20Sopenharmony_ci 588c2ecf20Sopenharmony_ci if (!file->elf->changed) 598c2ecf20Sopenharmony_ci return 0; 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_ci return elf_write(file->elf); 628c2ecf20Sopenharmony_ci } 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_ci if (!strcmp(argv[0], "dump")) { 658c2ecf20Sopenharmony_ci if (argc != 2) 668c2ecf20Sopenharmony_ci usage_with_options(orc_usage, check_options); 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_ci objname = argv[1]; 698c2ecf20Sopenharmony_ci 708c2ecf20Sopenharmony_ci return orc_dump(objname); 718c2ecf20Sopenharmony_ci } 728c2ecf20Sopenharmony_ci 738c2ecf20Sopenharmony_ci usage_with_options(orc_usage, check_options); 748c2ecf20Sopenharmony_ci 758c2ecf20Sopenharmony_ci return 0; 768c2ecf20Sopenharmony_ci} 77