GNU Linux-libre 6.1.90-gnu
[releases.git] / tools / objtool / include / objtool / warn.h
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 /*
3  * Copyright (C) 2015 Josh Poimboeuf <jpoimboe@redhat.com>
4  */
5
6 #ifndef _WARN_H
7 #define _WARN_H
8
9 #include <stdlib.h>
10 #include <string.h>
11 #include <sys/types.h>
12 #include <sys/stat.h>
13 #include <fcntl.h>
14 #include <objtool/builtin.h>
15 #include <objtool/elf.h>
16
17 extern const char *objname;
18
19 static inline char *offstr(struct section *sec, unsigned long offset)
20 {
21         bool is_text = (sec->sh.sh_flags & SHF_EXECINSTR);
22         struct symbol *sym = NULL;
23         char *str;
24         int len;
25
26         if (is_text)
27                 sym = find_func_containing(sec, offset);
28         if (!sym)
29                 sym = find_symbol_containing(sec, offset);
30
31         if (sym) {
32                 str = malloc(strlen(sym->name) + strlen(sec->name) + 40);
33                 len = sprintf(str, "%s+0x%lx", sym->name, offset - sym->offset);
34                 if (opts.sec_address)
35                         sprintf(str+len, " (%s+0x%lx)", sec->name, offset);
36         } else {
37                 str = malloc(strlen(sec->name) + 20);
38                 sprintf(str, "%s+0x%lx", sec->name, offset);
39         }
40
41         return str;
42 }
43
44 #define WARN(format, ...)                               \
45         fprintf(stderr,                                 \
46                 "%s: warning: objtool: " format "\n",   \
47                 objname, ##__VA_ARGS__)
48
49 #define WARN_FUNC(format, sec, offset, ...)             \
50 ({                                                      \
51         char *_str = offstr(sec, offset);               \
52         WARN("%s: " format, _str, ##__VA_ARGS__);       \
53         free(_str);                                     \
54 })
55
56 #define BT_FUNC(format, insn, ...)                      \
57 ({                                                      \
58         struct instruction *_insn = (insn);             \
59         char *_str = offstr(_insn->sec, _insn->offset); \
60         WARN("  %s: " format, _str, ##__VA_ARGS__);     \
61         free(_str);                                     \
62 })
63
64 #define WARN_ELF(format, ...)                           \
65         WARN(format ": %s", ##__VA_ARGS__, elf_errmsg(-1))
66
67 #endif /* _WARN_H */