mirror_ubuntu-kernels/tools/objtool/include/objtool/warn.h
Josh Poimboeuf 99c0beb547 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
2022-04-22 12:32:02 +02:00

68 lines
1.5 KiB
C

/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Copyright (C) 2015 Josh Poimboeuf <jpoimboe@redhat.com>
*/
#ifndef _WARN_H
#define _WARN_H
#include <stdlib.h>
#include <string.h>
#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)
{
bool is_text = (sec->sh.sh_flags & SHF_EXECINSTR);
struct symbol *sym = NULL;
char *str;
int len;
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 {
str = malloc(strlen(sec->name) + 20);
sprintf(str, "%s+0x%lx", sec->name, offset);
}
return str;
}
#define WARN(format, ...) \
fprintf(stderr, \
"%s: warning: objtool: " format "\n", \
objname, ##__VA_ARGS__)
#define WARN_FUNC(format, sec, offset, ...) \
({ \
char *_str = offstr(sec, offset); \
WARN("%s: " format, _str, ##__VA_ARGS__); \
free(_str); \
})
#define BT_FUNC(format, insn, ...) \
({ \
struct instruction *_insn = (insn); \
char *_str = offstr(_insn->sec, _insn->offset); \
WARN(" %s: " format, _str, ##__VA_ARGS__); \
free(_str); \
})
#define WARN_ELF(format, ...) \
WARN(format ": %s", ##__VA_ARGS__, elf_errmsg(-1))
#endif /* _WARN_H */