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: Nick Desaulniers <ndesaulniers@google.com> Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Reviewed-by: Miroslav Benes <mbenes@suse.cz> Link: https://lkml.kernel.org/r/2cea4d5299d53d1a4c09212a6ad7820aa46fda7a.1650300597.git.jpoimboe@redhat.com
This commit is contained in:
Родитель
2bc3dec705
Коммит
99c0beb547
|
@ -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"),
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@ struct opts {
|
|||
bool module;
|
||||
bool no_fp;
|
||||
bool no_unreachable;
|
||||
bool sec_address;
|
||||
bool stats;
|
||||
bool vmlinux;
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче