Commit 6545eb03 authored by Julien Thierry's avatar Julien Thierry Committed by Josh Poimboeuf
Browse files

objtool: Move object file loading out of check()



Structure objtool_file can be used by different subcommands. In fact
it already is, by check and orc.

Provide a function that allows to initialize objtool_file, that builtin
can call, without relying on check to do the correct setup for them and
explicitly hand the objtool_file to them.

Reviewed-by: default avatarMiroslav Benes <mbenes@suse.cz>
Signed-off-by: default avatarJulien Thierry <jthierry@redhat.com>
Signed-off-by: default avatarJosh Poimboeuf <jpoimboe@redhat.com>
parent 7c9903c9
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@ const struct option check_options[] = {
int cmd_check(int argc, const char **argv)
{
	const char *objname, *s;
	struct objtool_file *file;

	argc = parse_options(argc, argv, check_options, check_usage, 0);

@@ -53,5 +54,9 @@ int cmd_check(int argc, const char **argv)
	if (s && !s[9])
		vmlinux = true;

	return check(objname, false);
	file = objtool_open_read(objname);
	if (!file)
		return 1;

	return check(file, false);
}
+7 −1
Original line number Diff line number Diff line
@@ -31,13 +31,19 @@ int cmd_orc(int argc, const char **argv)
		usage_with_options(orc_usage, check_options);

	if (!strncmp(argv[0], "gen", 3)) {
		struct objtool_file *file;

		argc = parse_options(argc, argv, check_options, orc_usage, 0);
		if (argc != 1)
			usage_with_options(orc_usage, check_options);

		objname = argv[0];

		return check(objname, true);
		file = objtool_open_read(objname);
		if (!file)
			return 1;

		return check(file, true);
	}

	if (!strcmp(argv[0], "dump")) {
+13 −29
Original line number Diff line number Diff line
@@ -28,7 +28,6 @@ struct alternative {
	bool skip_orig;
};

const char *objname;
struct cfi_init_state initial_func_cfi;

struct instruction *find_insn(struct objtool_file *file,
@@ -2909,37 +2908,22 @@ static int validate_reachable_instructions(struct objtool_file *file)
	return 0;
}

static struct objtool_file file;

int check(const char *_objname, bool orc)
int check(struct objtool_file *file, bool orc)
{
	int ret, warnings = 0;

	objname = _objname;

	file.elf = elf_open_read(objname, O_RDWR);
	if (!file.elf)
		return 1;

	INIT_LIST_HEAD(&file.insn_list);
	hash_init(file.insn_hash);
	INIT_LIST_HEAD(&file.static_call_list);
	file.c_file = !vmlinux && find_section_by_name(file.elf, ".comment");
	file.ignore_unreachables = no_unreachable;
	file.hints = false;

	arch_initial_func_cfi_state(&initial_func_cfi);

	ret = decode_sections(&file);
	ret = decode_sections(file);
	if (ret < 0)
		goto out;
	warnings += ret;

	if (list_empty(&file.insn_list))
	if (list_empty(&file->insn_list))
		goto out;

	if (vmlinux && !validate_dup) {
		ret = validate_vmlinux_functions(&file);
		ret = validate_vmlinux_functions(file);
		if (ret < 0)
			goto out;

@@ -2948,46 +2932,46 @@ int check(const char *_objname, bool orc)
	}

	if (retpoline) {
		ret = validate_retpoline(&file);
		ret = validate_retpoline(file);
		if (ret < 0)
			return ret;
		warnings += ret;
	}

	ret = validate_functions(&file);
	ret = validate_functions(file);
	if (ret < 0)
		goto out;
	warnings += ret;

	ret = validate_unwind_hints(&file, NULL);
	ret = validate_unwind_hints(file, NULL);
	if (ret < 0)
		goto out;
	warnings += ret;

	if (!warnings) {
		ret = validate_reachable_instructions(&file);
		ret = validate_reachable_instructions(file);
		if (ret < 0)
			goto out;
		warnings += ret;
	}

	ret = create_static_call_sections(&file);
	ret = create_static_call_sections(file);
	if (ret < 0)
		goto out;
	warnings += ret;

	if (orc) {
		ret = create_orc(&file);
		ret = create_orc(file);
		if (ret < 0)
			goto out;

		ret = create_orc_sections(&file);
		ret = create_orc_sections(file);
		if (ret < 0)
			goto out;
	}

	if (file.elf->changed) {
		ret = elf_write(file.elf);
	if (file->elf->changed) {
		ret = elf_write(file->elf);
		if (ret < 0)
			goto out;
	}
+30 −0
Original line number Diff line number Diff line
@@ -22,6 +22,8 @@
#include <linux/kernel.h>

#include "builtin.h"
#include "objtool.h"
#include "warn.h"

struct cmd_struct {
	const char *name;
@@ -39,6 +41,34 @@ static struct cmd_struct objtool_cmds[] = {

bool help;

const char *objname;
static struct objtool_file file;

struct objtool_file *objtool_open_read(const char *_objname)
{
	if (objname) {
		if (strcmp(objname, _objname)) {
			WARN("won't handle more than one file at a time");
			return NULL;
		}
		return &file;
	}
	objname = _objname;

	file.elf = elf_open_read(objname, O_RDWR);
	if (!file.elf)
		return NULL;

	INIT_LIST_HEAD(&file.insn_list);
	hash_init(file.insn_hash);
	INIT_LIST_HEAD(&file.static_call_list);
	file.c_file = !vmlinux && find_section_by_name(file.elf, ".comment");
	file.ignore_unreachables = no_unreachable;
	file.hints = false;

	return &file;
}

static void cmd_usage(void)
{
	unsigned int i, longest = 0;
+3 −1
Original line number Diff line number Diff line
@@ -20,7 +20,9 @@ struct objtool_file {
	bool ignore_unreachables, c_file, hints, rodata;
};

int check(const char *objname, bool orc);
struct objtool_file *objtool_open_read(const char *_objname);

int check(struct objtool_file *file, bool orc);
int orc_dump(const char *objname);
int create_orc(struct objtool_file *file);
int create_orc_sections(struct objtool_file *file);
Loading