11ccea77eSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
2442f04c3SJosh Poimboeuf /*
3442f04c3SJosh Poimboeuf * Copyright (C) 2015 Josh Poimboeuf <[email protected]>
4442f04c3SJosh Poimboeuf */
5442f04c3SJosh Poimboeuf
6442f04c3SJosh Poimboeuf #include <stdio.h>
7442f04c3SJosh Poimboeuf #include <stdbool.h>
8442f04c3SJosh Poimboeuf #include <string.h>
9442f04c3SJosh Poimboeuf #include <stdlib.h>
108ad15c69SPeter Zijlstra #include <unistd.h>
11442f04c3SJosh Poimboeuf #include <subcmd/exec-cmd.h>
12442f04c3SJosh Poimboeuf #include <subcmd/pager.h>
1300614597SArnaldo Carvalho de Melo #include <linux/kernel.h>
14442f04c3SJosh Poimboeuf
157786032eSVasily Gorbik #include <objtool/builtin.h>
167786032eSVasily Gorbik #include <objtool/objtool.h>
177786032eSVasily Gorbik #include <objtool/warn.h>
18442f04c3SJosh Poimboeuf
19442f04c3SJosh Poimboeuf bool help;
20442f04c3SJosh Poimboeuf
216545eb03SJulien Thierry static struct objtool_file file;
226545eb03SJulien Thierry
objtool_open_read(const char * filename)235a406031SJosh Poimboeuf struct objtool_file *objtool_open_read(const char *filename)
246545eb03SJulien Thierry {
255a406031SJosh Poimboeuf if (file.elf) {
26*3e7be635SJosh Poimboeuf ERROR("won't handle more than one file at a time");
276545eb03SJulien Thierry return NULL;
286545eb03SJulien Thierry }
296545eb03SJulien Thierry
305a406031SJosh Poimboeuf file.elf = elf_open_read(filename, O_RDWR);
316545eb03SJulien Thierry if (!file.elf)
326545eb03SJulien Thierry return NULL;
336545eb03SJulien Thierry
346545eb03SJulien Thierry hash_init(file.insn_hash);
3543d5430aSPeter Zijlstra INIT_LIST_HEAD(&file.retpoline_call_list);
36d9e9d230SPeter Zijlstra INIT_LIST_HEAD(&file.return_thunk_list);
376545eb03SJulien Thierry INIT_LIST_HEAD(&file.static_call_list);
3899d00215SPeter Zijlstra INIT_LIST_HEAD(&file.mcount_loc_list);
3989bc853eSPeter Zijlstra INIT_LIST_HEAD(&file.endbr_list);
4000abd384SPeter Zijlstra INIT_LIST_HEAD(&file.call_list);
412daf7fabSJosh Poimboeuf file.ignore_unreachables = opts.no_unreachable;
426545eb03SJulien Thierry file.hints = false;
436545eb03SJulien Thierry
446545eb03SJulien Thierry return &file;
456545eb03SJulien Thierry }
466545eb03SJulien Thierry
objtool_pv_add(struct objtool_file * f,int idx,struct symbol * func)47c5995abeSJosh Poimboeuf int objtool_pv_add(struct objtool_file *f, int idx, struct symbol *func)
48db2b0c5dSPeter Zijlstra {
492daf7fabSJosh Poimboeuf if (!opts.noinstr)
50c5995abeSJosh Poimboeuf return 0;
51db2b0c5dSPeter Zijlstra
52db2b0c5dSPeter Zijlstra if (!f->pv_ops) {
53*3e7be635SJosh Poimboeuf ERROR("paravirt confusion");
54c5995abeSJosh Poimboeuf return -1;
55db2b0c5dSPeter Zijlstra }
56db2b0c5dSPeter Zijlstra
57db2b0c5dSPeter Zijlstra /*
58db2b0c5dSPeter Zijlstra * These functions will be patched into native code,
59db2b0c5dSPeter Zijlstra * see paravirt_patch().
60db2b0c5dSPeter Zijlstra */
61db2b0c5dSPeter Zijlstra if (!strcmp(func->name, "_paravirt_nop") ||
62db2b0c5dSPeter Zijlstra !strcmp(func->name, "_paravirt_ident_64"))
63c5995abeSJosh Poimboeuf return 0;
64db2b0c5dSPeter Zijlstra
65988f0168SPeter Zijlstra /* already added this function */
66988f0168SPeter Zijlstra if (!list_empty(&func->pv_target))
67c5995abeSJosh Poimboeuf return 0;
68988f0168SPeter Zijlstra
69db2b0c5dSPeter Zijlstra list_add(&func->pv_target, &f->pv_ops[idx].targets);
70db2b0c5dSPeter Zijlstra f->pv_ops[idx].clean = false;
71c5995abeSJosh Poimboeuf return 0;
72db2b0c5dSPeter Zijlstra }
73db2b0c5dSPeter Zijlstra
main(int argc,const char ** argv)74442f04c3SJosh Poimboeuf int main(int argc, const char **argv)
75442f04c3SJosh Poimboeuf {
76442f04c3SJosh Poimboeuf static const char *UNUSED = "OBJTOOL_NOT_IMPLEMENTED";
77442f04c3SJosh Poimboeuf
78442f04c3SJosh Poimboeuf /* libsubcmd init */
79442f04c3SJosh Poimboeuf exec_cmd_init("objtool", UNUSED, UNUSED, UNUSED);
80442f04c3SJosh Poimboeuf pager_init(UNUSED);
81442f04c3SJosh Poimboeuf
82e959c279SAaron Plattner return objtool_run(argc, argv);
83442f04c3SJosh Poimboeuf }
84