Commit 99c0beb5 authored by Josh Poimboeuf's avatar Josh Poimboeuf Committed by Peter Zijlstra
Browse files

objtool: Add option to print section addresses



To help prevent objtool users from having to do math to convert function
addresses to section addresses, and to help out with finding data
addresses reported by IBT validation, add an option to print the section
address in addition to the function address.

Normal:

  vmlinux.o: warning: objtool: fixup_exception()+0x2d1: unreachable instruction

With '--sec-address':

  vmlinux.o: warning: objtool: fixup_exception()+0x2d1 (.text+0x76c51): unreachable instruction

Suggested-by: default avatarNick Desaulniers <ndesaulniers@google.com>
Signed-off-by: default avatarJosh Poimboeuf <jpoimboe@redhat.com>
Signed-off-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: default avatarMiroslav Benes <mbenes@suse.cz>
Link: https://lkml.kernel.org/r/2cea4d5299d53d1a4c09212a6ad7820aa46fda7a.1650300597.git.jpoimboe@redhat.com
parent 2bc3dec7
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -50,6 +50,7 @@ const struct option check_options[] = {
	OPT_BOOLEAN(0, "module", &opts.module, "object is part of a kernel module"),
	OPT_BOOLEAN(0, "no-fp", &opts.no_fp, "skip frame pointer validation"),
	OPT_BOOLEAN(0, "no-unreachable", &opts.no_unreachable, "skip 'unreachable instruction' warnings"),
	OPT_BOOLEAN(0, "sec-address", &opts.sec_address, "print section addresses in warnings"),
	OPT_BOOLEAN(0, "stats", &opts.stats, "print statistics"),
	OPT_BOOLEAN(0, "vmlinux", &opts.vmlinux, "vmlinux.o validation"),

+1 −0
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ struct opts {
	bool module;
	bool no_fp;
	bool no_unreachable;
	bool sec_address;
	bool stats;
	bool vmlinux;
};
+17 −14
Original line number Diff line number Diff line
@@ -11,30 +11,33 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <objtool/builtin.h>
#include <objtool/elf.h>

extern const char *objname;

static inline char *offstr(struct section *sec, unsigned long offset)
{
	struct symbol *func;
	char *name, *str;
	unsigned long name_off;
	bool is_text = (sec->sh.sh_flags & SHF_EXECINSTR);
	struct symbol *sym = NULL;
	char *str;
	int len;

	func = find_func_containing(sec, offset);
	if (!func)
		func = find_symbol_containing(sec, offset);
	if (func) {
		name = func->name;
		name_off = offset - func->offset;
	if (is_text)
		sym = find_func_containing(sec, offset);
	if (!sym)
		sym = find_symbol_containing(sec, offset);

	if (sym) {
		str = malloc(strlen(sym->name) + strlen(sec->name) + 40);
		len = sprintf(str, "%s+0x%lx", sym->name, offset - sym->offset);
		if (opts.sec_address)
			sprintf(str+len, " (%s+0x%lx)", sec->name, offset);
	} else {
		name = sec->name;
		name_off = offset;
		str = malloc(strlen(sec->name) + 20);
		sprintf(str, "%s+0x%lx", sec->name, offset);
	}

	str = malloc(strlen(name) + 20);
	sprintf(str, "%s+0x%lx", name, name_off);

	return str;
}