File Index
Files and directories
Sign in
FILE

objtool.c

File preview with syntax highlighting.

linux-6.19.14/tools/objtool/objtool.c C
  1// SPDX-License-Identifier: GPL-2.0-or-later
  2/*
  3 * Copyright (C) 2015 Josh Poimboeuf <jpoimboe@redhat.com>
  4 */
  5
  6#include <stdio.h>
  7#include <stdbool.h>
  8#include <string.h>
  9#include <stdlib.h>
 10#include <unistd.h>
 11#include <subcmd/exec-cmd.h>
 12#include <subcmd/pager.h>
 13#include <linux/kernel.h>
 14
 15#include <objtool/builtin.h>
 16#include <objtool/objtool.h>
 17#include <objtool/warn.h>
 18
 19bool debug;
 20int indent;
 21
 22static struct objtool_file file;
 23
 24struct objtool_file *objtool_open_read(const char *filename)
 25{
 26	if (file.elf) {
 27		ERROR("won't handle more than one file at a time");
 28		return NULL;
 29	}
 30
 31	file.elf = elf_open_read(filename, O_RDWR);
 32	if (!file.elf)
 33		return NULL;
 34
 35	hash_init(file.insn_hash);
 36	INIT_LIST_HEAD(&file.retpoline_call_list);
 37	INIT_LIST_HEAD(&file.return_thunk_list);
 38	INIT_LIST_HEAD(&file.static_call_list);
 39	INIT_LIST_HEAD(&file.mcount_loc_list);
 40	INIT_LIST_HEAD(&file.endbr_list);
 41	INIT_LIST_HEAD(&file.call_list);
 42	file.ignore_unreachables = opts.no_unreachable;
 43	file.hints = false;
 44
 45	return &file;
 46}
 47
 48int objtool_pv_add(struct objtool_file *f, int idx, struct symbol *func)
 49{
 50	if (!opts.noinstr)
 51		return 0;
 52
 53	if (!f->pv_ops) {
 54		ERROR("paravirt confusion");
 55		return -1;
 56	}
 57
 58	/*
 59	 * These functions will be patched into native code,
 60	 * see paravirt_patch().
 61	 */
 62	if (!strcmp(func->name, "_paravirt_nop") ||
 63	    !strcmp(func->name, "_paravirt_ident_64"))
 64		return 0;
 65
 66	/* already added this function */
 67	if (!list_empty(&func->pv_target))
 68		return 0;
 69
 70	list_add(&func->pv_target, &f->pv_ops[idx].targets);
 71	f->pv_ops[idx].clean = false;
 72	return 0;
 73}
 74
 75char *top_level_dir(const char *file)
 76{
 77	ssize_t len, self_len, file_len;
 78	char self[PATH_MAX], *str;
 79	int i;
 80
 81	len = readlink("/proc/self/exe", self, sizeof(self) - 1);
 82	if (len <= 0)
 83		return NULL;
 84	self[len] = '\0';
 85
 86	for (i = 0; i < 3; i++) {
 87		char *s = strrchr(self, '/');
 88		if (!s)
 89			return NULL;
 90		*s = '\0';
 91	}
 92
 93	self_len = strlen(self);
 94	file_len = strlen(file);
 95
 96	str = malloc(self_len + file_len + 2);
 97	if (!str)
 98		return NULL;
 99
100	memcpy(str, self, self_len);
101	str[self_len] = '/';
102	strcpy(str + self_len + 1, file);
103
104	return str;
105}
106
107int main(int argc, const char **argv)
108{
109	static const char *UNUSED = "OBJTOOL_NOT_IMPLEMENTED";
110
111	if (init_signal_handler())
112		return -1;
113
114	/* libsubcmd init */
115	exec_cmd_init("objtool", UNUSED, UNUSED, UNUSED);
116	pager_init(UNUSED);
117
118	if (argc > 1 && !strcmp(argv[1], "klp")) {
119		argc--;
120		argv++;
121		return cmd_klp(argc, argv);
122	}
123
124	return objtool_run(argc, argv);
125}
~/ Read-only file preview.