brintos

brintos / linux-shallow public Read only

0
0
Text · 2.8 KiB · f40febd Raw
151 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*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 help;20 21const char *objname;22static struct objtool_file file;23 24static bool objtool_create_backup(const char *_objname)25{26	int len = strlen(_objname);27	char *buf, *base, *name = malloc(len+6);28	int s, d, l, t;29 30	if (!name) {31		perror("failed backup name malloc");32		return false;33	}34 35	strcpy(name, _objname);36	strcpy(name + len, ".orig");37 38	d = open(name, O_CREAT|O_WRONLY|O_TRUNC, 0644);39	if (d < 0) {40		perror("failed to create backup file");41		return false;42	}43 44	s = open(_objname, O_RDONLY);45	if (s < 0) {46		perror("failed to open orig file");47		return false;48	}49 50	buf = malloc(4096);51	if (!buf) {52		perror("failed backup data malloc");53		return false;54	}55 56	while ((l = read(s, buf, 4096)) > 0) {57		base = buf;58		do {59			t = write(d, base, l);60			if (t < 0) {61				perror("failed backup write");62				return false;63			}64			base += t;65			l -= t;66		} while (l);67	}68 69	if (l < 0) {70		perror("failed backup read");71		return false;72	}73 74	free(name);75	free(buf);76	close(d);77	close(s);78 79	return true;80}81 82struct objtool_file *objtool_open_read(const char *_objname)83{84	if (objname) {85		if (strcmp(objname, _objname)) {86			WARN("won't handle more than one file at a time");87			return NULL;88		}89		return &file;90	}91	objname = _objname;92 93	file.elf = elf_open_read(objname, O_RDWR);94	if (!file.elf)95		return NULL;96 97	if (opts.backup && !objtool_create_backup(objname)) {98		WARN("can't create backup file");99		return NULL;100	}101 102	hash_init(file.insn_hash);103	INIT_LIST_HEAD(&file.retpoline_call_list);104	INIT_LIST_HEAD(&file.return_thunk_list);105	INIT_LIST_HEAD(&file.static_call_list);106	INIT_LIST_HEAD(&file.mcount_loc_list);107	INIT_LIST_HEAD(&file.endbr_list);108	INIT_LIST_HEAD(&file.call_list);109	file.ignore_unreachables = opts.no_unreachable;110	file.hints = false;111 112	return &file;113}114 115void objtool_pv_add(struct objtool_file *f, int idx, struct symbol *func)116{117	if (!opts.noinstr)118		return;119 120	if (!f->pv_ops) {121		WARN("paravirt confusion");122		return;123	}124 125	/*126	 * These functions will be patched into native code,127	 * see paravirt_patch().128	 */129	if (!strcmp(func->name, "_paravirt_nop") ||130	    !strcmp(func->name, "_paravirt_ident_64"))131		return;132 133	/* already added this function */134	if (!list_empty(&func->pv_target))135		return;136 137	list_add(&func->pv_target, &f->pv_ops[idx].targets);138	f->pv_ops[idx].clean = false;139}140 141int main(int argc, const char **argv)142{143	static const char *UNUSED = "OBJTOOL_NOT_IMPLEMENTED";144 145	/* libsubcmd init */146	exec_cmd_init("objtool", UNUSED, UNUSED, UNUSED);147	pager_init(UNUSED);148 149	return objtool_run(argc, argv);150}151