~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/objtool/check.c

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /tools/objtool/check.c (Version linux-6.12-rc7) and /tools/objtool/check.c (Version linux-4.15.18)


  1 // SPDX-License-Identifier: GPL-2.0-or-later   << 
  2 /*                                                  1 /*
  3  * Copyright (C) 2015-2017 Josh Poimboeuf <jpo      2  * Copyright (C) 2015-2017 Josh Poimboeuf <jpoimboe@redhat.com>
                                                   >>   3  *
                                                   >>   4  * This program is free software; you can redistribute it and/or
                                                   >>   5  * modify it under the terms of the GNU General Public License
                                                   >>   6  * as published by the Free Software Foundation; either version 2
                                                   >>   7  * of the License, or (at your option) any later version.
                                                   >>   8  *
                                                   >>   9  * This program is distributed in the hope that it will be useful,
                                                   >>  10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
                                                   >>  11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                                                   >>  12  * GNU General Public License for more details.
                                                   >>  13  *
                                                   >>  14  * You should have received a copy of the GNU General Public License
                                                   >>  15  * along with this program; if not, see <http://www.gnu.org/licenses/>.
  4  */                                                16  */
  5                                                    17 
  6 #include <string.h>                                18 #include <string.h>
  7 #include <stdlib.h>                                19 #include <stdlib.h>
  8 #include <inttypes.h>                          << 
  9 #include <sys/mman.h>                          << 
 10                                                    20 
 11 #include <objtool/builtin.h>                   !!  21 #include "builtin.h"
 12 #include <objtool/cfi.h>                       !!  22 #include "check.h"
 13 #include <objtool/arch.h>                      !!  23 #include "elf.h"
 14 #include <objtool/check.h>                     !!  24 #include "special.h"
 15 #include <objtool/special.h>                   !!  25 #include "arch.h"
 16 #include <objtool/warn.h>                      !!  26 #include "warn.h"
 17 #include <objtool/endianness.h>                << 
 18                                                    27 
 19 #include <linux/objtool_types.h>               << 
 20 #include <linux/hashtable.h>                       28 #include <linux/hashtable.h>
 21 #include <linux/kernel.h>                          29 #include <linux/kernel.h>
 22 #include <linux/static_call_types.h>           << 
 23 #include <linux/string.h>                      << 
 24                                                    30 
 25 struct alternative {                               31 struct alternative {
 26         struct alternative *next;              !!  32         struct list_head list;
 27         struct instruction *insn;                  33         struct instruction *insn;
 28         bool skip_orig;                        << 
 29 };                                                 34 };
 30                                                    35 
 31 static unsigned long nr_cfi, nr_cfi_reused, nr !!  36 const char *objname;
 32                                                !!  37 struct cfi_state initial_func_cfi;
 33 static struct cfi_init_state initial_func_cfi; << 
 34 static struct cfi_state init_cfi;              << 
 35 static struct cfi_state func_cfi;              << 
 36 static struct cfi_state force_undefined_cfi;   << 
 37                                                    38 
 38 struct instruction *find_insn(struct objtool_f     39 struct instruction *find_insn(struct objtool_file *file,
 39                               struct section *     40                               struct section *sec, unsigned long offset)
 40 {                                                  41 {
 41         struct instruction *insn;                  42         struct instruction *insn;
 42                                                    43 
 43         hash_for_each_possible(file->insn_hash !!  44         hash_for_each_possible(file->insn_hash, insn, hash, offset)
 44                 if (insn->sec == sec && insn->     45                 if (insn->sec == sec && insn->offset == offset)
 45                         return insn;               46                         return insn;
 46         }                                      << 
 47                                                    47 
 48         return NULL;                               48         return NULL;
 49 }                                                  49 }
 50                                                    50 
 51 struct instruction *next_insn_same_sec(struct  !!  51 static struct instruction *next_insn_same_sec(struct objtool_file *file,
 52                                        struct  << 
 53 {                                              << 
 54         if (insn->idx == INSN_CHUNK_MAX)       << 
 55                 return find_insn(file, insn->s << 
 56                                                << 
 57         insn++;                                << 
 58         if (!insn->len)                        << 
 59                 return NULL;                   << 
 60                                                << 
 61         return insn;                           << 
 62 }                                              << 
 63                                                << 
 64 static struct instruction *next_insn_same_func << 
 65                                                << 
 66 {                                              << 
 67         struct instruction *next = next_insn_s << 
 68         struct symbol *func = insn_func(insn); << 
 69                                                << 
 70         if (!func)                             << 
 71                 return NULL;                   << 
 72                                                << 
 73         if (next && insn_func(next) == func)   << 
 74                 return next;                   << 
 75                                                << 
 76         /* Check if we're already in the subfu << 
 77         if (func == func->cfunc)               << 
 78                 return NULL;                   << 
 79                                                << 
 80         /* Move to the subfunction: */         << 
 81         return find_insn(file, func->cfunc->se << 
 82 }                                              << 
 83                                                << 
 84 static struct instruction *prev_insn_same_sec( << 
 85                                                << 
 86 {                                              << 
 87         if (insn->idx == 0) {                  << 
 88                 if (insn->prev_len)            << 
 89                         return find_insn(file, << 
 90                 return NULL;                   << 
 91         }                                      << 
 92                                                << 
 93         return insn - 1;                       << 
 94 }                                              << 
 95                                                << 
 96 static struct instruction *prev_insn_same_sym( << 
 97                                                    52                                               struct instruction *insn)
 98 {                                                  53 {
 99         struct instruction *prev = prev_insn_s !!  54         struct instruction *next = list_next_entry(insn, list);
100                                                    55 
101         if (prev && insn_func(prev) == insn_fu !!  56         if (!next || &next->list == &file->insn_list || next->sec != insn->sec)
102                 return prev;                   !!  57                 return NULL;
103                                                    58 
104         return NULL;                           !!  59         return next;
105 }                                                  60 }
106                                                    61 
107 #define for_each_insn(file, insn)              << 
108         for (struct section *__sec, *__fake =  << 
109              __fake; __fake = NULL)            << 
110                 for_each_sec(file, __sec)      << 
111                         sec_for_each_insn(file << 
112                                                << 
113 #define func_for_each_insn(file, func, insn)       62 #define func_for_each_insn(file, func, insn)                            \
114         for (insn = find_insn(file, func->sec,     63         for (insn = find_insn(file, func->sec, func->offset);           \
115              insn;                             !!  64              insn && &insn->list != &file->insn_list &&                 \
116              insn = next_insn_same_func(file,  !!  65                 insn->sec == func->sec &&                               \
117                                                !!  66                 insn->offset < func->offset + func->len;                \
118 #define sym_for_each_insn(file, sym, insn)     !!  67              insn = list_next_entry(insn, list))
119         for (insn = find_insn(file, sym->sec,  !!  68 
120              insn && insn->offset < sym->offse !!  69 #define func_for_each_insn_continue_reverse(file, func, insn)           \
121              insn = next_insn_same_sec(file, i !!  70         for (insn = list_prev_entry(insn, list);                        \
122                                                !!  71              &insn->list != &file->insn_list &&                         \
123 #define sym_for_each_insn_continue_reverse(fil !!  72                 insn->sec == func->sec && insn->offset >= func->offset; \
124         for (insn = prev_insn_same_sec(file, i !!  73              insn = list_prev_entry(insn, list))
125              insn && insn->offset >= sym->offs << 
126              insn = prev_insn_same_sec(file, i << 
127                                                    74 
128 #define sec_for_each_insn_from(file, insn)         75 #define sec_for_each_insn_from(file, insn)                              \
129         for (; insn; insn = next_insn_same_sec     76         for (; insn; insn = next_insn_same_sec(file, insn))
130                                                    77 
131 #define sec_for_each_insn_continue(file, insn)     78 #define sec_for_each_insn_continue(file, insn)                          \
132         for (insn = next_insn_same_sec(file, i     79         for (insn = next_insn_same_sec(file, insn); insn;               \
133              insn = next_insn_same_sec(file, i     80              insn = next_insn_same_sec(file, insn))
134                                                    81 
135 static inline struct symbol *insn_call_dest(st << 
136 {                                              << 
137         if (insn->type == INSN_JUMP_DYNAMIC || << 
138             insn->type == INSN_CALL_DYNAMIC)   << 
139                 return NULL;                   << 
140                                                << 
141         return insn->_call_dest;               << 
142 }                                              << 
143                                                << 
144 static inline struct reloc *insn_jump_table(st << 
145 {                                              << 
146         if (insn->type == INSN_JUMP_DYNAMIC || << 
147             insn->type == INSN_CALL_DYNAMIC)   << 
148                 return insn->_jump_table;      << 
149                                                << 
150         return NULL;                           << 
151 }                                              << 
152                                                << 
153 static bool is_jump_table_jump(struct instruct << 
154 {                                              << 
155         struct alt_group *alt_group = insn->al << 
156                                                << 
157         if (insn_jump_table(insn))             << 
158                 return true;                   << 
159                                                << 
160         /* Retpoline alternative for a jump ta << 
161         return alt_group && alt_group->orig_gr << 
162                insn_jump_table(alt_group->orig << 
163 }                                              << 
164                                                << 
165 static bool is_sibling_call(struct instruction << 
166 {                                              << 
167         /*                                     << 
168          * Assume only STT_FUNC calls have jum << 
169          */                                    << 
170         if (insn_func(insn)) {                 << 
171                 /* An indirect jump is either  << 
172                 if (insn->type == INSN_JUMP_DY << 
173                         return !is_jump_table_ << 
174         }                                      << 
175                                                << 
176         /* add_jump_destinations() sets insn_c << 
177         return (is_static_jump(insn) && insn_c << 
178 }                                              << 
179                                                << 
180 /*                                             << 
181  * Checks if a string ends with another.       << 
182  */                                            << 
183 static bool str_ends_with(const char *s, const << 
184 {                                              << 
185         const int slen = strlen(s);            << 
186         const int sublen = strlen(sub);        << 
187                                                << 
188         if (sublen > slen)                     << 
189                 return 0;                      << 
190                                                << 
191         return !memcmp(s + slen - sublen, sub, << 
192 }                                              << 
193                                                << 
194 /*                                                 82 /*
195  * Checks if a function is a Rust "noreturn" o !!  83  * Check if the function has been manually whitelisted with the
196  */                                            !!  84  * STACK_FRAME_NON_STANDARD macro, or if it should be automatically whitelisted
197 static bool is_rust_noreturn(const struct symb !!  85  * due to its use of a context switching instruction.
198 {                                              !!  86  */
199         /*                                     !!  87 static bool ignore_func(struct objtool_file *file, struct symbol *func)
200          * If it does not start with "_R", the !!  88 {
201          */                                    !!  89         struct rela *rela;
202         if (strncmp(func->name, "_R", 2))      !!  90 
203                 return false;                  !!  91         /* check for STACK_FRAME_NON_STANDARD */
                                                   >>  92         if (file->whitelist && file->whitelist->rela)
                                                   >>  93                 list_for_each_entry(rela, &file->whitelist->rela->rela_list, list) {
                                                   >>  94                         if (rela->sym->type == STT_SECTION &&
                                                   >>  95                             rela->sym->sec == func->sec &&
                                                   >>  96                             rela->addend == func->offset)
                                                   >>  97                                 return true;
                                                   >>  98                         if (rela->sym->type == STT_FUNC && rela->sym == func)
                                                   >>  99                                 return true;
                                                   >> 100                 }
204                                                   101 
205         /*                                     !! 102         return false;
206          * These are just heuristics -- we do  << 
207          * name, due to the crate disambiguato << 
208          * as well as changes to the source co << 
209          * these come from the Rust standard l << 
210          */                                    << 
211         return str_ends_with(func->name, "_4co << 
212                str_ends_with(func->name, "_4co << 
213                str_ends_with(func->name, "_4co << 
214                str_ends_with(func->name, "_4co << 
215                str_ends_with(func->name, "_4co << 
216                str_ends_with(func->name, "_4co << 
217                str_ends_with(func->name, "_4co << 
218                str_ends_with(func->name, "_4co << 
219                str_ends_with(func->name, "_4co << 
220                str_ends_with(func->name, "_4co << 
221                strstr(func->name, "_4core9pani << 
222                (strstr(func->name, "_4core5sli << 
223                 str_ends_with(func->name, "_fa << 
224 }                                                 103 }
225                                                   104 
226 /*                                                105 /*
227  * This checks to see if the given function is    106  * This checks to see if the given function is a "noreturn" function.
228  *                                                107  *
229  * For global functions which are outside the     108  * For global functions which are outside the scope of this object file, we
230  * have to keep a manual list of them.            109  * have to keep a manual list of them.
231  *                                                110  *
232  * For local functions, we have to detect them    111  * For local functions, we have to detect them manually by simply looking for
233  * the lack of a return instruction.              112  * the lack of a return instruction.
                                                   >> 113  *
                                                   >> 114  * Returns:
                                                   >> 115  *  -1: error
                                                   >> 116  *   0: no dead end
                                                   >> 117  *   1: dead end
234  */                                               118  */
235 static bool __dead_end_function(struct objtool !! 119 static int __dead_end_function(struct objtool_file *file, struct symbol *func,
236                                 int recursion) !! 120                                int recursion)
237 {                                                 121 {
238         int i;                                    122         int i;
239         struct instruction *insn;                 123         struct instruction *insn;
240         bool empty = true;                        124         bool empty = true;
241                                                   125 
242 #define NORETURN(func) __stringify(func),      !! 126         /*
                                                   >> 127          * Unfortunately these have to be hard coded because the noreturn
                                                   >> 128          * attribute isn't provided in ELF data.
                                                   >> 129          */
243         static const char * const global_noret    130         static const char * const global_noreturns[] = {
244 #include "noreturns.h"                         !! 131                 "__stack_chk_fail",
                                                   >> 132                 "panic",
                                                   >> 133                 "do_exit",
                                                   >> 134                 "do_task_dead",
                                                   >> 135                 "__module_put_and_exit",
                                                   >> 136                 "complete_and_exit",
                                                   >> 137                 "kvm_spurious_fault",
                                                   >> 138                 "__reiserfs_panic",
                                                   >> 139                 "lbug_with_loc",
                                                   >> 140                 "fortify_panic",
245         };                                        141         };
246 #undef NORETURN                                << 
247                                                << 
248         if (!func)                             << 
249                 return false;                  << 
250                                                   142 
251         if (func->bind == STB_GLOBAL || func-> !! 143         if (func->bind == STB_WEAK)
252                 if (is_rust_noreturn(func))    !! 144                 return 0;
253                         return true;           << 
254                                                   145 
                                                   >> 146         if (func->bind == STB_GLOBAL)
255                 for (i = 0; i < ARRAY_SIZE(glo    147                 for (i = 0; i < ARRAY_SIZE(global_noreturns); i++)
256                         if (!strcmp(func->name    148                         if (!strcmp(func->name, global_noreturns[i]))
257                                 return true;   !! 149                                 return 1;
258         }                                      << 
259                                                << 
260         if (func->bind == STB_WEAK)            << 
261                 return false;                  << 
262                                                << 
263         if (!func->len)                        << 
264                 return false;                  << 
265                                                   150 
266         insn = find_insn(file, func->sec, func !! 151         if (!func->sec)
267         if (!insn || !insn_func(insn))         !! 152                 return 0;
268                 return false;                  << 
269                                                   153 
270         func_for_each_insn(file, func, insn) {    154         func_for_each_insn(file, func, insn) {
271                 empty = false;                    155                 empty = false;
272                                                   156 
273                 if (insn->type == INSN_RETURN)    157                 if (insn->type == INSN_RETURN)
274                         return false;          !! 158                         return 0;
275         }                                         159         }
276                                                   160 
277         if (empty)                                161         if (empty)
278                 return false;                  !! 162                 return 0;
279                                                   163 
280         /*                                        164         /*
281          * A function can have a sibling call     165          * A function can have a sibling call instead of a return.  In that
282          * case, the function's dead-end statu    166          * case, the function's dead-end status depends on whether the target
283          * of the sibling call returns.           167          * of the sibling call returns.
284          */                                       168          */
285         func_for_each_insn(file, func, insn) {    169         func_for_each_insn(file, func, insn) {
286                 if (is_sibling_call(insn)) {   !! 170                 if (insn->sec != func->sec ||
                                                   >> 171                     insn->offset >= func->offset + func->len)
                                                   >> 172                         break;
                                                   >> 173 
                                                   >> 174                 if (insn->type == INSN_JUMP_UNCONDITIONAL) {
287                         struct instruction *de    175                         struct instruction *dest = insn->jump_dest;
                                                   >> 176                         struct symbol *dest_func;
288                                                   177 
289                         if (!dest)                178                         if (!dest)
290                                 /* sibling cal    179                                 /* sibling call to another file */
291                                 return false;  !! 180                                 return 0;
292                                                   181 
293                         /* local sibling call  !! 182                         if (dest->sec != func->sec ||
294                         if (recursion == 5) {  !! 183                             dest->offset < func->offset ||
295                                 /*             !! 184                             dest->offset >= func->offset + func->len) {
296                                  * Infinite re !! 185                                 /* local sibling call */
297                                  * sibling cal !! 186                                 dest_func = find_symbol_by_offset(dest->sec,
298                                  * rare case.  !! 187                                                                   dest->offset);
299                                  */            !! 188                                 if (!dest_func)
300                                 return false;  !! 189                                         continue;
301                         }                      !! 190 
                                                   >> 191                                 if (recursion == 5) {
                                                   >> 192                                         WARN_FUNC("infinite recursion (objtool bug!)",
                                                   >> 193                                                   dest->sec, dest->offset);
                                                   >> 194                                         return -1;
                                                   >> 195                                 }
302                                                   196 
303                         return __dead_end_func !! 197                                 return __dead_end_function(file, dest_func,
                                                   >> 198                                                            recursion + 1);
                                                   >> 199                         }
304                 }                                 200                 }
                                                   >> 201 
                                                   >> 202                 if (insn->type == INSN_JUMP_DYNAMIC && list_empty(&insn->alts))
                                                   >> 203                         /* sibling call */
                                                   >> 204                         return 0;
305         }                                         205         }
306                                                   206 
307         return true;                           !! 207         return 1;
308 }                                                 208 }
309                                                   209 
310 static bool dead_end_function(struct objtool_f !! 210 static int dead_end_function(struct objtool_file *file, struct symbol *func)
311 {                                                 211 {
312         return __dead_end_function(file, func,    212         return __dead_end_function(file, func, 0);
313 }                                                 213 }
314                                                   214 
315 static void init_cfi_state(struct cfi_state *c !! 215 static void clear_insn_state(struct insn_state *state)
316 {                                                 216 {
317         int i;                                    217         int i;
318                                                   218 
319         for (i = 0; i < CFI_NUM_REGS; i++) {   << 
320                 cfi->regs[i].base = CFI_UNDEFI << 
321                 cfi->vals[i].base = CFI_UNDEFI << 
322         }                                      << 
323         cfi->cfa.base = CFI_UNDEFINED;         << 
324         cfi->drap_reg = CFI_UNDEFINED;         << 
325         cfi->drap_offset = -1;                 << 
326 }                                              << 
327                                                << 
328 static void init_insn_state(struct objtool_fil << 
329                             struct section *se << 
330 {                                              << 
331         memset(state, 0, sizeof(*state));         219         memset(state, 0, sizeof(*state));
332         init_cfi_state(&state->cfi);           !! 220         state->cfa.base = CFI_UNDEFINED;
333                                                !! 221         for (i = 0; i < CFI_NUM_REGS; i++) {
334         /*                                     !! 222                 state->regs[i].base = CFI_UNDEFINED;
335          * We need the full vmlinux for noinst !! 223                 state->vals[i].base = CFI_UNDEFINED;
336          * not correctly determine insn_call_d << 
337          * do not have a section).             << 
338          */                                    << 
339         if (opts.link && opts.noinstr && sec)  << 
340                 state->noinstr = sec->noinstr; << 
341 }                                              << 
342                                                << 
343 static struct cfi_state *cfi_alloc(void)       << 
344 {                                              << 
345         struct cfi_state *cfi = calloc(1, size << 
346         if (!cfi) {                            << 
347                 WARN("calloc failed");         << 
348                 exit(1);                       << 
349         }                                      << 
350         nr_cfi++;                              << 
351         return cfi;                            << 
352 }                                              << 
353                                                << 
354 static int cfi_bits;                           << 
355 static struct hlist_head *cfi_hash;            << 
356                                                << 
357 static inline bool cficmp(struct cfi_state *cf << 
358 {                                              << 
359         return memcmp((void *)cfi1 + sizeof(cf << 
360                       (void *)cfi2 + sizeof(cf << 
361                       sizeof(struct cfi_state) << 
362 }                                              << 
363                                                << 
364 static inline u32 cfi_key(struct cfi_state *cf << 
365 {                                              << 
366         return jhash((void *)cfi + sizeof(cfi- << 
367                      sizeof(*cfi) - sizeof(cfi << 
368 }                                              << 
369                                                << 
370 static struct cfi_state *cfi_hash_find_or_add( << 
371 {                                              << 
372         struct hlist_head *head = &cfi_hash[ha << 
373         struct cfi_state *obj;                 << 
374                                                << 
375         hlist_for_each_entry(obj, head, hash)  << 
376                 if (!cficmp(cfi, obj)) {       << 
377                         nr_cfi_cache++;        << 
378                         return obj;            << 
379                 }                              << 
380         }                                      << 
381                                                << 
382         obj = cfi_alloc();                     << 
383         *obj = *cfi;                           << 
384         hlist_add_head(&obj->hash, head);      << 
385                                                << 
386         return obj;                            << 
387 }                                              << 
388                                                << 
389 static void cfi_hash_add(struct cfi_state *cfi << 
390 {                                              << 
391         struct hlist_head *head = &cfi_hash[ha << 
392                                                << 
393         hlist_add_head(&cfi->hash, head);      << 
394 }                                              << 
395                                                << 
396 static void *cfi_hash_alloc(unsigned long size << 
397 {                                              << 
398         cfi_bits = max(10, ilog2(size));       << 
399         cfi_hash = mmap(NULL, sizeof(struct hl << 
400                         PROT_READ|PROT_WRITE,  << 
401                         MAP_PRIVATE|MAP_ANON,  << 
402         if (cfi_hash == (void *)-1L) {         << 
403                 WARN("mmap fail cfi_hash");    << 
404                 cfi_hash = NULL;               << 
405         }  else if (opts.stats) {              << 
406                 printf("cfi_bits: %d\n", cfi_b << 
407         }                                         224         }
408                                                !! 225         state->drap_reg = CFI_UNDEFINED;
409         return cfi_hash;                       !! 226         state->drap_offset = -1;
410 }                                                 227 }
411                                                   228 
412 static unsigned long nr_insns;                 << 
413 static unsigned long nr_insns_visited;         << 
414                                                << 
415 /*                                                229 /*
416  * Call the arch-specific instruction decoder     230  * Call the arch-specific instruction decoder for all the instructions and add
417  * them to the global instruction list.           231  * them to the global instruction list.
418  */                                               232  */
419 static int decode_instructions(struct objtool_    233 static int decode_instructions(struct objtool_file *file)
420 {                                                 234 {
421         struct section *sec;                      235         struct section *sec;
422         struct symbol *func;                      236         struct symbol *func;
423         unsigned long offset;                     237         unsigned long offset;
424         struct instruction *insn;                 238         struct instruction *insn;
425         int ret;                                  239         int ret;
426                                                   240 
427         for_each_sec(file, sec) {                 241         for_each_sec(file, sec) {
428                 struct instruction *insns = NU << 
429                 u8 prev_len = 0;               << 
430                 u8 idx = 0;                    << 
431                                                   242 
432                 if (!(sec->sh.sh_flags & SHF_E    243                 if (!(sec->sh.sh_flags & SHF_EXECINSTR))
433                         continue;                 244                         continue;
434                                                   245 
435                 if (strcmp(sec->name, ".altins    246                 if (strcmp(sec->name, ".altinstr_replacement") &&
436                     strcmp(sec->name, ".altins    247                     strcmp(sec->name, ".altinstr_aux") &&
437                     strncmp(sec->name, ".disca    248                     strncmp(sec->name, ".discard.", 9))
438                         sec->text = true;         249                         sec->text = true;
439                                                   250 
440                 if (!strcmp(sec->name, ".noins !! 251                 for (offset = 0; offset < sec->len; offset += insn->len) {
441                     !strcmp(sec->name, ".entry !! 252                         insn = malloc(sizeof(*insn));
442                     !strcmp(sec->name, ".cpuid !! 253                         if (!insn) {
443                     !strncmp(sec->name, ".text !! 254                                 WARN("malloc failed");
444                         sec->noinstr = true;   !! 255                                 return -1;
445                                                << 
446                 /*                             << 
447                  * .init.text code is ran befo << 
448                  * strictly need retpolines, e << 
449                  * loaded late, they very much << 
450                  * .init.text                  << 
451                  */                            << 
452                 if (!strcmp(sec->name, ".init. << 
453                         sec->init = true;      << 
454                                                << 
455                 for (offset = 0; offset < sec- << 
456                         if (!insns || idx == I << 
457                                 insns = calloc << 
458                                 if (!insns) {  << 
459                                         WARN(" << 
460                                         return << 
461                                 }              << 
462                                 idx = 0;       << 
463                         } else {               << 
464                                 idx++;         << 
465                         }                         256                         }
466                         insn = &insns[idx];    !! 257                         memset(insn, 0, sizeof(*insn));
467                         insn->idx = idx;       !! 258                         INIT_LIST_HEAD(&insn->alts);
                                                   >> 259                         clear_insn_state(&insn->state);
468                                                   260 
469                         INIT_LIST_HEAD(&insn-> << 
470                         insn->sec = sec;          261                         insn->sec = sec;
471                         insn->offset = offset;    262                         insn->offset = offset;
472                         insn->prev_len = prev_ << 
473                                                   263 
474                         ret = arch_decode_inst !! 264                         ret = arch_decode_instruction(file->elf, sec, offset,
475                                                !! 265                                                       sec->len - offset,
476                                                !! 266                                                       &insn->len, &insn->type,
                                                   >> 267                                                       &insn->immediate,
                                                   >> 268                                                       &insn->stack_op);
477                         if (ret)                  269                         if (ret)
478                                 return ret;    !! 270                                 goto err;
479                                                << 
480                         prev_len = insn->len;  << 
481                                                   271 
482                         /*                     !! 272                         if (!insn->type || insn->type > INSN_LAST) {
483                          * By default, "ud2" i !! 273                                 WARN_FUNC("invalid instruction type %d",
484                          * annotated, because  !! 274                                           insn->sec, insn->offset, insn->type);
485                          * divide-by-zero case !! 275                                 ret = -1;
486                          */                    !! 276                                 goto err;
487                         if (insn->type == INSN !! 277                         }
488                                 insn->dead_end << 
489                                                   278 
490                         hash_add(file->insn_ha !! 279                         hash_add(file->insn_hash, &insn->hash, insn->offset);
491                         nr_insns++;            !! 280                         list_add_tail(&insn->list, &file->insn_list);
492                 }                                 281                 }
493                                                   282 
494 //              printf("%s: last chunk used: % !! 283                 list_for_each_entry(func, &sec->symbol_list, list) {
495                                                !! 284                         if (func->type != STT_FUNC)
496                 sec_for_each_sym(sec, func) {  << 
497                         if (func->type != STT_ << 
498                                 continue;      << 
499                                                << 
500                         if (func->offset == se << 
501                                 /* Heuristic:  << 
502                                 if (func->type << 
503                                         contin << 
504                                 WARN("%s(): ST << 
505                                      func->nam << 
506                                 return -1;     << 
507                         }                      << 
508                                                << 
509                         if (func->embedded_ins << 
510                                 continue;         285                                 continue;
511                                                   286 
512                         if (!find_insn(file, s    287                         if (!find_insn(file, sec, func->offset)) {
513                                 WARN("%s(): ca    288                                 WARN("%s(): can't find starting instruction",
514                                      func->nam    289                                      func->name);
515                                 return -1;        290                                 return -1;
516                         }                         291                         }
517                                                   292 
518                         sym_for_each_insn(file !! 293                         func_for_each_insn(file, func, insn)
519                                 insn->sym = fu !! 294                                 if (!insn->func)
520                                 if (func->type !! 295                                         insn->func = func;
521                                     insn->type << 
522                                     list_empty << 
523                                         if (in << 
524                                                << 
525                                                << 
526                                         } else << 
527                                                << 
528                                         }      << 
529                                 }              << 
530                         }                      << 
531                 }                                 296                 }
532         }                                         297         }
533                                                   298 
534         if (opts.stats)                        << 
535                 printf("nr_insns: %lu\n", nr_i << 
536                                                << 
537         return 0;                              << 
538 }                                              << 
539                                                << 
540 /*                                             << 
541  * Read the pv_ops[] .data table to find the s << 
542  */                                            << 
543 static int add_pv_ops(struct objtool_file *fil << 
544 {                                              << 
545         struct symbol *sym, *func;             << 
546         unsigned long off, end;                << 
547         struct reloc *reloc;                   << 
548         int idx;                               << 
549                                                << 
550         sym = find_symbol_by_name(file->elf, s << 
551         if (!sym)                              << 
552                 return 0;                      << 
553                                                << 
554         off = sym->offset;                     << 
555         end = off + sym->len;                  << 
556         for (;;) {                             << 
557                 reloc = find_reloc_by_dest_ran << 
558                 if (!reloc)                    << 
559                         break;                 << 
560                                                << 
561                 func = reloc->sym;             << 
562                 if (func->type == STT_SECTION) << 
563                         func = find_symbol_by_ << 
564                                                << 
565                                                << 
566                 idx = (reloc_offset(reloc) - s << 
567                                                << 
568                 objtool_pv_add(file, idx, func << 
569                                                << 
570                 off = reloc_offset(reloc) + 1; << 
571                 if (off > end)                 << 
572                         break;                 << 
573         }                                      << 
574                                                << 
575         return 0;                              << 
576 }                                              << 
577                                                << 
578 /*                                             << 
579  * Allocate and initialize file->pv_ops[].     << 
580  */                                            << 
581 static int init_pv_ops(struct objtool_file *fi << 
582 {                                              << 
583         static const char *pv_ops_tables[] = { << 
584                 "pv_ops",                      << 
585                 "xen_cpu_ops",                 << 
586                 "xen_irq_ops",                 << 
587                 "xen_mmu_ops",                 << 
588                 NULL,                          << 
589         };                                     << 
590         const char *pv_ops;                    << 
591         struct symbol *sym;                    << 
592         int idx, nr;                           << 
593                                                << 
594         if (!opts.noinstr)                     << 
595                 return 0;                      << 
596                                                << 
597         file->pv_ops = NULL;                   << 
598                                                << 
599         sym = find_symbol_by_name(file->elf, " << 
600         if (!sym)                              << 
601                 return 0;                      << 
602                                                << 
603         nr = sym->len / sizeof(unsigned long); << 
604         file->pv_ops = calloc(sizeof(struct pv << 
605         if (!file->pv_ops)                     << 
606                 return -1;                     << 
607                                                << 
608         for (idx = 0; idx < nr; idx++)         << 
609                 INIT_LIST_HEAD(&file->pv_ops[i << 
610                                                << 
611         for (idx = 0; (pv_ops = pv_ops_tables[ << 
612                 add_pv_ops(file, pv_ops);      << 
613                                                << 
614         return 0;                                 299         return 0;
615 }                                              << 
616                                                << 
617 static struct instruction *find_last_insn(stru << 
618                                           stru << 
619 {                                              << 
620         struct instruction *insn = NULL;       << 
621         unsigned int offset;                   << 
622         unsigned int end = (sec->sh.sh_size >  << 
623                                                   300 
624         for (offset = sec->sh.sh_size - 1; off !! 301 err:
625                 insn = find_insn(file, sec, of !! 302         free(insn);
626                                                !! 303         return ret;
627         return insn;                           << 
628 }                                                 304 }
629                                                   305 
630 /*                                                306 /*
631  * Mark "ud2" instructions and manually annota    307  * Mark "ud2" instructions and manually annotated dead ends.
632  */                                               308  */
633 static int add_dead_ends(struct objtool_file *    309 static int add_dead_ends(struct objtool_file *file)
634 {                                                 310 {
635         struct section *rsec;                  !! 311         struct section *sec;
636         struct reloc *reloc;                   !! 312         struct rela *rela;
637         struct instruction *insn;                 313         struct instruction *insn;
638         uint64_t offset;                       !! 314         bool found;
                                                   >> 315 
                                                   >> 316         /*
                                                   >> 317          * By default, "ud2" is a dead end unless otherwise annotated, because
                                                   >> 318          * GCC 7 inserts it for certain divide-by-zero cases.
                                                   >> 319          */
                                                   >> 320         for_each_insn(file, insn)
                                                   >> 321                 if (insn->type == INSN_BUG)
                                                   >> 322                         insn->dead_end = true;
639                                                   323 
640         /*                                        324         /*
641          * Check for manually annotated dead e    325          * Check for manually annotated dead ends.
642          */                                       326          */
643         rsec = find_section_by_name(file->elf, !! 327         sec = find_section_by_name(file->elf, ".rela.discard.unreachable");
644         if (!rsec)                             !! 328         if (!sec)
645                 goto reachable;                   329                 goto reachable;
646                                                   330 
647         for_each_reloc(rsec, reloc) {          !! 331         list_for_each_entry(rela, &sec->rela_list, list) {
648                 if (reloc->sym->type == STT_SE !! 332                 if (rela->sym->type != STT_SECTION) {
649                         offset = reloc_addend( !! 333                         WARN("unexpected relocation symbol type in %s", sec->name);
650                 } else if (reloc->sym->local_l << 
651                         offset = reloc->sym->o << 
652                 } else {                       << 
653                         WARN("unexpected reloc << 
654                         return -1;                334                         return -1;
655                 }                                 335                 }
656                                                !! 336                 insn = find_insn(file, rela->sym->sec, rela->addend);
657                 insn = find_insn(file, reloc-> << 
658                 if (insn)                         337                 if (insn)
659                         insn = prev_insn_same_ !! 338                         insn = list_prev_entry(insn, list);
660                 else if (offset == reloc->sym- !! 339                 else if (rela->addend == rela->sym->sec->len) {
661                         insn = find_last_insn( !! 340                         found = false;
662                         if (!insn) {           !! 341                         list_for_each_entry_reverse(insn, &file->insn_list, list) {
663                                 WARN("can't fi !! 342                                 if (insn->sec == rela->sym->sec) {
664                                      reloc->sy !! 343                                         found = true;
                                                   >> 344                                         break;
                                                   >> 345                                 }
                                                   >> 346                         }
                                                   >> 347 
                                                   >> 348                         if (!found) {
                                                   >> 349                                 WARN("can't find unreachable insn at %s+0x%x",
                                                   >> 350                                      rela->sym->sec->name, rela->addend);
665                                 return -1;        351                                 return -1;
666                         }                         352                         }
667                 } else {                          353                 } else {
668                         WARN("can't find unrea !! 354                         WARN("can't find unreachable insn at %s+0x%x",
669                              reloc->sym->sec-> !! 355                              rela->sym->sec->name, rela->addend);
670                         return -1;                356                         return -1;
671                 }                                 357                 }
672                                                   358 
673                 insn->dead_end = true;            359                 insn->dead_end = true;
674         }                                         360         }
675                                                   361 
676 reachable:                                        362 reachable:
677         /*                                        363         /*
678          * These manually annotated reachable     364          * These manually annotated reachable checks are needed for GCC 4.4,
679          * where the Linux unreachable() macro    365          * where the Linux unreachable() macro isn't supported.  In that case
680          * GCC doesn't know the "ud2" is fatal    366          * GCC doesn't know the "ud2" is fatal, so it generates code as if it's
681          * not a dead end.                        367          * not a dead end.
682          */                                       368          */
683         rsec = find_section_by_name(file->elf, !! 369         sec = find_section_by_name(file->elf, ".rela.discard.reachable");
684         if (!rsec)                             !! 370         if (!sec)
685                 return 0;                         371                 return 0;
686                                                   372 
687         for_each_reloc(rsec, reloc) {          !! 373         list_for_each_entry(rela, &sec->rela_list, list) {
688                 if (reloc->sym->type == STT_SE !! 374                 if (rela->sym->type != STT_SECTION) {
689                         offset = reloc_addend( !! 375                         WARN("unexpected relocation symbol type in %s", sec->name);
690                 } else if (reloc->sym->local_l << 
691                         offset = reloc->sym->o << 
692                 } else {                       << 
693                         WARN("unexpected reloc << 
694                         return -1;                376                         return -1;
695                 }                                 377                 }
696                                                !! 378                 insn = find_insn(file, rela->sym->sec, rela->addend);
697                 insn = find_insn(file, reloc-> << 
698                 if (insn)                         379                 if (insn)
699                         insn = prev_insn_same_ !! 380                         insn = list_prev_entry(insn, list);
700                 else if (offset == reloc->sym- !! 381                 else if (rela->addend == rela->sym->sec->len) {
701                         insn = find_last_insn( !! 382                         found = false;
702                         if (!insn) {           !! 383                         list_for_each_entry_reverse(insn, &file->insn_list, list) {
703                                 WARN("can't fi !! 384                                 if (insn->sec == rela->sym->sec) {
704                                      reloc->sy !! 385                                         found = true;
                                                   >> 386                                         break;
                                                   >> 387                                 }
                                                   >> 388                         }
                                                   >> 389 
                                                   >> 390                         if (!found) {
                                                   >> 391                                 WARN("can't find reachable insn at %s+0x%x",
                                                   >> 392                                      rela->sym->sec->name, rela->addend);
705                                 return -1;        393                                 return -1;
706                         }                         394                         }
707                 } else {                          395                 } else {
708                         WARN("can't find reach !! 396                         WARN("can't find reachable insn at %s+0x%x",
709                              reloc->sym->sec-> !! 397                              rela->sym->sec->name, rela->addend);
710                         return -1;                398                         return -1;
711                 }                                 399                 }
712                                                   400 
713                 insn->dead_end = false;           401                 insn->dead_end = false;
714         }                                         402         }
715                                                   403 
716         return 0;                                 404         return 0;
717 }                                                 405 }
718                                                   406 
719 static int create_static_call_sections(struct  << 
720 {                                              << 
721         struct static_call_site *site;         << 
722         struct section *sec;                   << 
723         struct instruction *insn;              << 
724         struct symbol *key_sym;                << 
725         char *key_name, *tmp;                  << 
726         int idx;                               << 
727                                                << 
728         sec = find_section_by_name(file->elf,  << 
729         if (sec) {                             << 
730                 INIT_LIST_HEAD(&file->static_c << 
731                 WARN("file already has .static << 
732                 return 0;                      << 
733         }                                      << 
734                                                << 
735         if (list_empty(&file->static_call_list << 
736                 return 0;                      << 
737                                                << 
738         idx = 0;                               << 
739         list_for_each_entry(insn, &file->stati << 
740                 idx++;                         << 
741                                                << 
742         sec = elf_create_section_pair(file->el << 
743                                       sizeof(* << 
744         if (!sec)                              << 
745                 return -1;                     << 
746                                                << 
747         /* Allow modules to modify the low bit << 
748         sec->sh.sh_flags |= SHF_WRITE;         << 
749                                                << 
750         idx = 0;                               << 
751         list_for_each_entry(insn, &file->stati << 
752                                                << 
753                 /* populate reloc for 'addr' * << 
754                 if (!elf_init_reloc_text_sym(f << 
755                                              i << 
756                                              i << 
757                         return -1;             << 
758                                                << 
759                 /* find key symbol */          << 
760                 key_name = strdup(insn_call_de << 
761                 if (!key_name) {               << 
762                         perror("strdup");      << 
763                         return -1;             << 
764                 }                              << 
765                 if (strncmp(key_name, STATIC_C << 
766                             STATIC_CALL_TRAMP_ << 
767                         WARN("static_call: tra << 
768                         free(key_name);        << 
769                         return -1;             << 
770                 }                              << 
771                 tmp = key_name + STATIC_CALL_T << 
772                 memcpy(tmp, STATIC_CALL_KEY_PR << 
773                                                << 
774                 key_sym = find_symbol_by_name( << 
775                 if (!key_sym) {                << 
776                         if (!opts.module) {    << 
777                                 WARN("static_c << 
778                                 free(key_name) << 
779                                 return -1;     << 
780                         }                      << 
781                                                << 
782                         /*                     << 
783                          * For modules(), the  << 
784                          * means the module ca << 
785                          * allowed to change t << 
786                          *                     << 
787                          * In that case we tem << 
788                          * trampoline address. << 
789                          * static_call_add_mod << 
790                          */                    << 
791                         key_sym = insn_call_de << 
792                 }                              << 
793                 free(key_name);                << 
794                                                << 
795                 /* populate reloc for 'key' */ << 
796                 if (!elf_init_reloc_data_sym(f << 
797                                              i << 
798                                              ( << 
799                                              i << 
800                         return -1;             << 
801                                                << 
802                 idx++;                         << 
803         }                                      << 
804                                                << 
805         return 0;                              << 
806 }                                              << 
807                                                << 
808 static int create_retpoline_sites_sections(str << 
809 {                                              << 
810         struct instruction *insn;              << 
811         struct section *sec;                   << 
812         int idx;                               << 
813                                                << 
814         sec = find_section_by_name(file->elf,  << 
815         if (sec) {                             << 
816                 WARN("file already has .retpol << 
817                 return 0;                      << 
818         }                                      << 
819                                                << 
820         idx = 0;                               << 
821         list_for_each_entry(insn, &file->retpo << 
822                 idx++;                         << 
823                                                << 
824         if (!idx)                              << 
825                 return 0;                      << 
826                                                << 
827         sec = elf_create_section_pair(file->el << 
828                                       sizeof(i << 
829         if (!sec)                              << 
830                 return -1;                     << 
831                                                << 
832         idx = 0;                               << 
833         list_for_each_entry(insn, &file->retpo << 
834                                                << 
835                 if (!elf_init_reloc_text_sym(f << 
836                                              i << 
837                                              i << 
838                         return -1;             << 
839                                                << 
840                 idx++;                         << 
841         }                                      << 
842                                                << 
843         return 0;                              << 
844 }                                              << 
845                                                << 
846 static int create_return_sites_sections(struct << 
847 {                                              << 
848         struct instruction *insn;              << 
849         struct section *sec;                   << 
850         int idx;                               << 
851                                                << 
852         sec = find_section_by_name(file->elf,  << 
853         if (sec) {                             << 
854                 WARN("file already has .return << 
855                 return 0;                      << 
856         }                                      << 
857                                                << 
858         idx = 0;                               << 
859         list_for_each_entry(insn, &file->retur << 
860                 idx++;                         << 
861                                                << 
862         if (!idx)                              << 
863                 return 0;                      << 
864                                                << 
865         sec = elf_create_section_pair(file->el << 
866                                       sizeof(i << 
867         if (!sec)                              << 
868                 return -1;                     << 
869                                                << 
870         idx = 0;                               << 
871         list_for_each_entry(insn, &file->retur << 
872                                                << 
873                 if (!elf_init_reloc_text_sym(f << 
874                                              i << 
875                                              i << 
876                         return -1;             << 
877                                                << 
878                 idx++;                         << 
879         }                                      << 
880                                                << 
881         return 0;                              << 
882 }                                              << 
883                                                << 
884 static int create_ibt_endbr_seal_sections(stru << 
885 {                                              << 
886         struct instruction *insn;              << 
887         struct section *sec;                   << 
888         int idx;                               << 
889                                                << 
890         sec = find_section_by_name(file->elf,  << 
891         if (sec) {                             << 
892                 WARN("file already has .ibt_en << 
893                 return 0;                      << 
894         }                                      << 
895                                                << 
896         idx = 0;                               << 
897         list_for_each_entry(insn, &file->endbr << 
898                 idx++;                         << 
899                                                << 
900         if (opts.stats) {                      << 
901                 printf("ibt: ENDBR at function << 
902                 printf("ibt: ENDBR inside func << 
903                 printf("ibt: superfluous ENDBR << 
904         }                                      << 
905                                                << 
906         if (!idx)                              << 
907                 return 0;                      << 
908                                                << 
909         sec = elf_create_section_pair(file->el << 
910                                       sizeof(i << 
911         if (!sec)                              << 
912                 return -1;                     << 
913                                                << 
914         idx = 0;                               << 
915         list_for_each_entry(insn, &file->endbr << 
916                                                << 
917                 int *site = (int *)sec->data-> << 
918                 struct symbol *sym = insn->sym << 
919                 *site = 0;                     << 
920                                                << 
921                 if (opts.module && sym && sym- << 
922                     insn->offset == sym->offse << 
923                     (!strcmp(sym->name, "init_ << 
924                      !strcmp(sym->name, "clean << 
925                         WARN("%s(): not an ind << 
926                                                << 
927                 if (!elf_init_reloc_text_sym(f << 
928                                              i << 
929                                              i << 
930                         return -1;             << 
931                                                << 
932                 idx++;                         << 
933         }                                      << 
934                                                << 
935         return 0;                              << 
936 }                                              << 
937                                                << 
938 static int create_cfi_sections(struct objtool_ << 
939 {                                              << 
940         struct section *sec;                   << 
941         struct symbol *sym;                    << 
942         int idx;                               << 
943                                                << 
944         sec = find_section_by_name(file->elf,  << 
945         if (sec) {                             << 
946                 INIT_LIST_HEAD(&file->call_lis << 
947                 WARN("file already has .cfi_si << 
948                 return 0;                      << 
949         }                                      << 
950                                                << 
951         idx = 0;                               << 
952         for_each_sym(file, sym) {              << 
953                 if (sym->type != STT_FUNC)     << 
954                         continue;              << 
955                                                << 
956                 if (strncmp(sym->name, "__cfi_ << 
957                         continue;              << 
958                                                << 
959                 idx++;                         << 
960         }                                      << 
961                                                << 
962         sec = elf_create_section_pair(file->el << 
963                                       sizeof(u << 
964         if (!sec)                              << 
965                 return -1;                     << 
966                                                << 
967         idx = 0;                               << 
968         for_each_sym(file, sym) {              << 
969                 if (sym->type != STT_FUNC)     << 
970                         continue;              << 
971                                                << 
972                 if (strncmp(sym->name, "__cfi_ << 
973                         continue;              << 
974                                                << 
975                 if (!elf_init_reloc_text_sym(f << 
976                                              i << 
977                                              s << 
978                         return -1;             << 
979                                                << 
980                 idx++;                         << 
981         }                                      << 
982                                                << 
983         return 0;                              << 
984 }                                              << 
985                                                << 
986 static int create_mcount_loc_sections(struct o << 
987 {                                              << 
988         size_t addr_size = elf_addr_size(file- << 
989         struct instruction *insn;              << 
990         struct section *sec;                   << 
991         int idx;                               << 
992                                                << 
993         sec = find_section_by_name(file->elf,  << 
994         if (sec) {                             << 
995                 INIT_LIST_HEAD(&file->mcount_l << 
996                 WARN("file already has __mcoun << 
997                 return 0;                      << 
998         }                                      << 
999                                                << 
1000         if (list_empty(&file->mcount_loc_list << 
1001                 return 0;                     << 
1002                                               << 
1003         idx = 0;                              << 
1004         list_for_each_entry(insn, &file->mcou << 
1005                 idx++;                        << 
1006                                               << 
1007         sec = elf_create_section_pair(file->e << 
1008                                       idx, id << 
1009         if (!sec)                             << 
1010                 return -1;                    << 
1011                                               << 
1012         sec->sh.sh_addralign = addr_size;     << 
1013                                               << 
1014         idx = 0;                              << 
1015         list_for_each_entry(insn, &file->mcou << 
1016                                               << 
1017                 struct reloc *reloc;          << 
1018                                               << 
1019                 reloc = elf_init_reloc_text_s << 
1020                                               << 
1021                 if (!reloc)                   << 
1022                         return -1;            << 
1023                                               << 
1024                 set_reloc_type(file->elf, rel << 
1025                                               << 
1026                 idx++;                        << 
1027         }                                     << 
1028                                               << 
1029         return 0;                             << 
1030 }                                             << 
1031                                               << 
1032 static int create_direct_call_sections(struct << 
1033 {                                             << 
1034         struct instruction *insn;             << 
1035         struct section *sec;                  << 
1036         int idx;                              << 
1037                                               << 
1038         sec = find_section_by_name(file->elf, << 
1039         if (sec) {                            << 
1040                 INIT_LIST_HEAD(&file->call_li << 
1041                 WARN("file already has .call_ << 
1042                 return 0;                     << 
1043         }                                     << 
1044                                               << 
1045         if (list_empty(&file->call_list))     << 
1046                 return 0;                     << 
1047                                               << 
1048         idx = 0;                              << 
1049         list_for_each_entry(insn, &file->call << 
1050                 idx++;                        << 
1051                                               << 
1052         sec = elf_create_section_pair(file->e << 
1053                                       sizeof( << 
1054         if (!sec)                             << 
1055                 return -1;                    << 
1056                                               << 
1057         idx = 0;                              << 
1058         list_for_each_entry(insn, &file->call << 
1059                                               << 
1060                 if (!elf_init_reloc_text_sym( << 
1061                                               << 
1062                                               << 
1063                         return -1;            << 
1064                                               << 
1065                 idx++;                        << 
1066         }                                     << 
1067                                               << 
1068         return 0;                             << 
1069 }                                             << 
1070                                               << 
1071 /*                                               407 /*
1072  * Warnings shouldn't be reported for ignored    408  * Warnings shouldn't be reported for ignored functions.
1073  */                                              409  */
1074 static void add_ignores(struct objtool_file *    410 static void add_ignores(struct objtool_file *file)
1075 {                                                411 {
1076         struct instruction *insn;                412         struct instruction *insn;
1077         struct section *rsec;                 !! 413         struct section *sec;
1078         struct symbol *func;                     414         struct symbol *func;
1079         struct reloc *reloc;                  << 
1080                                                  415 
1081         rsec = find_section_by_name(file->elf !! 416         for_each_sec(file, sec) {
1082         if (!rsec)                            !! 417                 list_for_each_entry(func, &sec->symbol_list, list) {
1083                 return;                       !! 418                         if (func->type != STT_FUNC)
1084                                               !! 419                                 continue;
1085         for_each_reloc(rsec, reloc) {         << 
1086                 switch (reloc->sym->type) {   << 
1087                 case STT_FUNC:                << 
1088                         func = reloc->sym;    << 
1089                         break;                << 
1090                                                  420 
1091                 case STT_SECTION:             !! 421                         if (!ignore_func(file, func))
1092                         func = find_func_by_o << 
1093                         if (!func)            << 
1094                                 continue;        422                                 continue;
1095                         break;                << 
1096                                                  423 
1097                 default:                      !! 424                         func_for_each_insn(file, func, insn)
1098                         WARN("unexpected relo !! 425                                 insn->ignore = true;
1099                              rsec->name, relo << 
1100                         continue;             << 
1101                 }                                426                 }
1102                                               << 
1103                 func_for_each_insn(file, func << 
1104                         insn->ignore = true;  << 
1105         }                                     << 
1106 }                                             << 
1107                                               << 
1108 /*                                            << 
1109  * This is a whitelist of functions that is a << 
1110  * The list is meant to be minimal and only c << 
1111  * ABI and a few functions used to implement  << 
1112  *                                            << 
1113  * These functions must not directly change A << 
1114  */                                           << 
1115 static const char *uaccess_safe_builtin[] = { << 
1116         /* KASAN */                           << 
1117         "kasan_report",                       << 
1118         "kasan_check_range",                  << 
1119         /* KASAN out-of-line */               << 
1120         "__asan_loadN_noabort",               << 
1121         "__asan_load1_noabort",               << 
1122         "__asan_load2_noabort",               << 
1123         "__asan_load4_noabort",               << 
1124         "__asan_load8_noabort",               << 
1125         "__asan_load16_noabort",              << 
1126         "__asan_storeN_noabort",              << 
1127         "__asan_store1_noabort",              << 
1128         "__asan_store2_noabort",              << 
1129         "__asan_store4_noabort",              << 
1130         "__asan_store8_noabort",              << 
1131         "__asan_store16_noabort",             << 
1132         "__kasan_check_read",                 << 
1133         "__kasan_check_write",                << 
1134         /* KASAN in-line */                   << 
1135         "__asan_report_load_n_noabort",       << 
1136         "__asan_report_load1_noabort",        << 
1137         "__asan_report_load2_noabort",        << 
1138         "__asan_report_load4_noabort",        << 
1139         "__asan_report_load8_noabort",        << 
1140         "__asan_report_load16_noabort",       << 
1141         "__asan_report_store_n_noabort",      << 
1142         "__asan_report_store1_noabort",       << 
1143         "__asan_report_store2_noabort",       << 
1144         "__asan_report_store4_noabort",       << 
1145         "__asan_report_store8_noabort",       << 
1146         "__asan_report_store16_noabort",      << 
1147         /* KCSAN */                           << 
1148         "__kcsan_check_access",               << 
1149         "__kcsan_mb",                         << 
1150         "__kcsan_wmb",                        << 
1151         "__kcsan_rmb",                        << 
1152         "__kcsan_release",                    << 
1153         "kcsan_found_watchpoint",             << 
1154         "kcsan_setup_watchpoint",             << 
1155         "kcsan_check_scoped_accesses",        << 
1156         "kcsan_disable_current",              << 
1157         "kcsan_enable_current_nowarn",        << 
1158         /* KCSAN/TSAN */                      << 
1159         "__tsan_func_entry",                  << 
1160         "__tsan_func_exit",                   << 
1161         "__tsan_read_range",                  << 
1162         "__tsan_write_range",                 << 
1163         "__tsan_read1",                       << 
1164         "__tsan_read2",                       << 
1165         "__tsan_read4",                       << 
1166         "__tsan_read8",                       << 
1167         "__tsan_read16",                      << 
1168         "__tsan_write1",                      << 
1169         "__tsan_write2",                      << 
1170         "__tsan_write4",                      << 
1171         "__tsan_write8",                      << 
1172         "__tsan_write16",                     << 
1173         "__tsan_read_write1",                 << 
1174         "__tsan_read_write2",                 << 
1175         "__tsan_read_write4",                 << 
1176         "__tsan_read_write8",                 << 
1177         "__tsan_read_write16",                << 
1178         "__tsan_volatile_read1",              << 
1179         "__tsan_volatile_read2",              << 
1180         "__tsan_volatile_read4",              << 
1181         "__tsan_volatile_read8",              << 
1182         "__tsan_volatile_read16",             << 
1183         "__tsan_volatile_write1",             << 
1184         "__tsan_volatile_write2",             << 
1185         "__tsan_volatile_write4",             << 
1186         "__tsan_volatile_write8",             << 
1187         "__tsan_volatile_write16",            << 
1188         "__tsan_atomic8_load",                << 
1189         "__tsan_atomic16_load",               << 
1190         "__tsan_atomic32_load",               << 
1191         "__tsan_atomic64_load",               << 
1192         "__tsan_atomic8_store",               << 
1193         "__tsan_atomic16_store",              << 
1194         "__tsan_atomic32_store",              << 
1195         "__tsan_atomic64_store",              << 
1196         "__tsan_atomic8_exchange",            << 
1197         "__tsan_atomic16_exchange",           << 
1198         "__tsan_atomic32_exchange",           << 
1199         "__tsan_atomic64_exchange",           << 
1200         "__tsan_atomic8_fetch_add",           << 
1201         "__tsan_atomic16_fetch_add",          << 
1202         "__tsan_atomic32_fetch_add",          << 
1203         "__tsan_atomic64_fetch_add",          << 
1204         "__tsan_atomic8_fetch_sub",           << 
1205         "__tsan_atomic16_fetch_sub",          << 
1206         "__tsan_atomic32_fetch_sub",          << 
1207         "__tsan_atomic64_fetch_sub",          << 
1208         "__tsan_atomic8_fetch_and",           << 
1209         "__tsan_atomic16_fetch_and",          << 
1210         "__tsan_atomic32_fetch_and",          << 
1211         "__tsan_atomic64_fetch_and",          << 
1212         "__tsan_atomic8_fetch_or",            << 
1213         "__tsan_atomic16_fetch_or",           << 
1214         "__tsan_atomic32_fetch_or",           << 
1215         "__tsan_atomic64_fetch_or",           << 
1216         "__tsan_atomic8_fetch_xor",           << 
1217         "__tsan_atomic16_fetch_xor",          << 
1218         "__tsan_atomic32_fetch_xor",          << 
1219         "__tsan_atomic64_fetch_xor",          << 
1220         "__tsan_atomic8_fetch_nand",          << 
1221         "__tsan_atomic16_fetch_nand",         << 
1222         "__tsan_atomic32_fetch_nand",         << 
1223         "__tsan_atomic64_fetch_nand",         << 
1224         "__tsan_atomic8_compare_exchange_stro << 
1225         "__tsan_atomic16_compare_exchange_str << 
1226         "__tsan_atomic32_compare_exchange_str << 
1227         "__tsan_atomic64_compare_exchange_str << 
1228         "__tsan_atomic8_compare_exchange_weak << 
1229         "__tsan_atomic16_compare_exchange_wea << 
1230         "__tsan_atomic32_compare_exchange_wea << 
1231         "__tsan_atomic64_compare_exchange_wea << 
1232         "__tsan_atomic8_compare_exchange_val" << 
1233         "__tsan_atomic16_compare_exchange_val << 
1234         "__tsan_atomic32_compare_exchange_val << 
1235         "__tsan_atomic64_compare_exchange_val << 
1236         "__tsan_atomic_thread_fence",         << 
1237         "__tsan_atomic_signal_fence",         << 
1238         "__tsan_unaligned_read16",            << 
1239         "__tsan_unaligned_write16",           << 
1240         /* KCOV */                            << 
1241         "write_comp_data",                    << 
1242         "check_kcov_mode",                    << 
1243         "__sanitizer_cov_trace_pc",           << 
1244         "__sanitizer_cov_trace_const_cmp1",   << 
1245         "__sanitizer_cov_trace_const_cmp2",   << 
1246         "__sanitizer_cov_trace_const_cmp4",   << 
1247         "__sanitizer_cov_trace_const_cmp8",   << 
1248         "__sanitizer_cov_trace_cmp1",         << 
1249         "__sanitizer_cov_trace_cmp2",         << 
1250         "__sanitizer_cov_trace_cmp4",         << 
1251         "__sanitizer_cov_trace_cmp8",         << 
1252         "__sanitizer_cov_trace_switch",       << 
1253         /* KMSAN */                           << 
1254         "kmsan_copy_to_user",                 << 
1255         "kmsan_disable_current",              << 
1256         "kmsan_enable_current",               << 
1257         "kmsan_report",                       << 
1258         "kmsan_unpoison_entry_regs",          << 
1259         "kmsan_unpoison_memory",              << 
1260         "__msan_chain_origin",                << 
1261         "__msan_get_context_state",           << 
1262         "__msan_instrument_asm_store",        << 
1263         "__msan_metadata_ptr_for_load_1",     << 
1264         "__msan_metadata_ptr_for_load_2",     << 
1265         "__msan_metadata_ptr_for_load_4",     << 
1266         "__msan_metadata_ptr_for_load_8",     << 
1267         "__msan_metadata_ptr_for_load_n",     << 
1268         "__msan_metadata_ptr_for_store_1",    << 
1269         "__msan_metadata_ptr_for_store_2",    << 
1270         "__msan_metadata_ptr_for_store_4",    << 
1271         "__msan_metadata_ptr_for_store_8",    << 
1272         "__msan_metadata_ptr_for_store_n",    << 
1273         "__msan_poison_alloca",               << 
1274         "__msan_warning",                     << 
1275         /* UBSAN */                           << 
1276         "ubsan_type_mismatch_common",         << 
1277         "__ubsan_handle_type_mismatch",       << 
1278         "__ubsan_handle_type_mismatch_v1",    << 
1279         "__ubsan_handle_shift_out_of_bounds", << 
1280         "__ubsan_handle_load_invalid_value",  << 
1281         /* STACKLEAK */                       << 
1282         "stackleak_track_stack",              << 
1283         /* misc */                            << 
1284         "csum_partial_copy_generic",          << 
1285         "copy_mc_fragile",                    << 
1286         "copy_mc_fragile_handle_tail",        << 
1287         "copy_mc_enhanced_fast_string",       << 
1288         "ftrace_likely_update", /* CONFIG_TRA << 
1289         "rep_stos_alternative",               << 
1290         "rep_movs_alternative",               << 
1291         "__copy_user_nocache",                << 
1292         NULL                                  << 
1293 };                                            << 
1294                                               << 
1295 static void add_uaccess_safe(struct objtool_f << 
1296 {                                             << 
1297         struct symbol *func;                  << 
1298         const char **name;                    << 
1299                                               << 
1300         if (!opts.uaccess)                    << 
1301                 return;                       << 
1302                                               << 
1303         for (name = uaccess_safe_builtin; *na << 
1304                 func = find_symbol_by_name(fi << 
1305                 if (!func)                    << 
1306                         continue;             << 
1307                                               << 
1308                 func->uaccess_safe = true;    << 
1309         }                                        427         }
1310 }                                                428 }
1311                                                  429 
1312 /*                                               430 /*
1313  * FIXME: For now, just ignore any alternativ    431  * FIXME: For now, just ignore any alternatives which add retpolines.  This is
1314  * a temporary hack, as it doesn't allow ORC     432  * a temporary hack, as it doesn't allow ORC to unwind from inside a retpoline.
1315  * But it at least allows objtool to understa    433  * But it at least allows objtool to understand the control flow *around* the
1316  * retpoline.                                    434  * retpoline.
1317  */                                              435  */
1318 static int add_ignore_alternatives(struct obj !! 436 static int add_nospec_ignores(struct objtool_file *file)
1319 {                                                437 {
1320         struct section *rsec;                 !! 438         struct section *sec;
1321         struct reloc *reloc;                  !! 439         struct rela *rela;
1322         struct instruction *insn;                440         struct instruction *insn;
1323                                                  441 
1324         rsec = find_section_by_name(file->elf !! 442         sec = find_section_by_name(file->elf, ".rela.discard.nospec");
1325         if (!rsec)                            !! 443         if (!sec)
1326                 return 0;                        444                 return 0;
1327                                                  445 
1328         for_each_reloc(rsec, reloc) {         !! 446         list_for_each_entry(rela, &sec->rela_list, list) {
1329                 if (reloc->sym->type != STT_S !! 447                 if (rela->sym->type != STT_SECTION) {
1330                         WARN("unexpected relo !! 448                         WARN("unexpected relocation symbol type in %s", sec->name);
1331                         return -1;               449                         return -1;
1332                 }                                450                 }
1333                                                  451 
1334                 insn = find_insn(file, reloc- !! 452                 insn = find_insn(file, rela->sym->sec, rela->addend);
1335                 if (!insn) {                     453                 if (!insn) {
1336                         WARN("bad .discard.ig !! 454                         WARN("bad .discard.nospec entry");
1337                         return -1;               455                         return -1;
1338                 }                                456                 }
1339                                                  457 
1340                 insn->ignore_alts = true;        458                 insn->ignore_alts = true;
1341         }                                        459         }
1342                                                  460 
1343         return 0;                                461         return 0;
1344 }                                                462 }
1345                                                  463 
1346 /*                                               464 /*
1347  * Symbols that replace INSN_CALL_DYNAMIC, ev << 
1348  * will be added to the .retpoline_sites sect << 
1349  */                                           << 
1350 __weak bool arch_is_retpoline(struct symbol * << 
1351 {                                             << 
1352         return false;                         << 
1353 }                                             << 
1354                                               << 
1355 /*                                            << 
1356  * Symbols that replace INSN_RETURN, every (t << 
1357  * will be added to the .return_sites section << 
1358  */                                           << 
1359 __weak bool arch_is_rethunk(struct symbol *sy << 
1360 {                                             << 
1361         return false;                         << 
1362 }                                             << 
1363                                               << 
1364 /*                                            << 
1365  * Symbols that are embedded inside other ins << 
1366  * code exists. These are mostly ignored for  << 
1367  */                                           << 
1368 __weak bool arch_is_embedded_insn(struct symb << 
1369 {                                             << 
1370         return false;                         << 
1371 }                                             << 
1372                                               << 
1373 static struct reloc *insn_reloc(struct objtoo << 
1374 {                                             << 
1375         struct reloc *reloc;                  << 
1376                                               << 
1377         if (insn->no_reloc)                   << 
1378                 return NULL;                  << 
1379                                               << 
1380         if (!file)                            << 
1381                 return NULL;                  << 
1382                                               << 
1383         reloc = find_reloc_by_dest_range(file << 
1384                                          insn << 
1385         if (!reloc) {                         << 
1386                 insn->no_reloc = 1;           << 
1387                 return NULL;                  << 
1388         }                                     << 
1389                                               << 
1390         return reloc;                         << 
1391 }                                             << 
1392                                               << 
1393 static void remove_insn_ops(struct instructio << 
1394 {                                             << 
1395         struct stack_op *op, *next;           << 
1396                                               << 
1397         for (op = insn->stack_ops; op; op = n << 
1398                 next = op->next;              << 
1399                 free(op);                     << 
1400         }                                     << 
1401         insn->stack_ops = NULL;               << 
1402 }                                             << 
1403                                               << 
1404 static void annotate_call_site(struct objtool << 
1405                                struct instruc << 
1406 {                                             << 
1407         struct reloc *reloc = insn_reloc(file << 
1408         struct symbol *sym = insn_call_dest(i << 
1409                                               << 
1410         if (!sym)                             << 
1411                 sym = reloc->sym;             << 
1412                                               << 
1413         /*                                    << 
1414          * Alternative replacement code is ju << 
1415          * sometimes copied to the original i << 
1416          * annotate it. (In the future we mig << 
1417          * original instruction if/when it ev << 
1418          */                                   << 
1419         if (!strcmp(insn->sec->name, ".altins << 
1420                 return;                       << 
1421                                               << 
1422         if (sym->static_call_tramp) {         << 
1423                 list_add_tail(&insn->call_nod << 
1424                 return;                       << 
1425         }                                     << 
1426                                               << 
1427         if (sym->retpoline_thunk) {           << 
1428                 list_add_tail(&insn->call_nod << 
1429                 return;                       << 
1430         }                                     << 
1431                                               << 
1432         /*                                    << 
1433          * Many compilers cannot disable KCOV << 
1434          * attribute so they need a little he << 
1435          * noinstr text.                      << 
1436          */                                   << 
1437         if (opts.hack_noinstr && insn->sec->n << 
1438                 if (reloc)                    << 
1439                         set_reloc_type(file-> << 
1440                                               << 
1441                 elf_write_insn(file->elf, ins << 
1442                                insn->offset,  << 
1443                                sibling ? arch << 
1444                                        : arch << 
1445                                               << 
1446                 insn->type = sibling ? INSN_R << 
1447                                               << 
1448                 if (sibling) {                << 
1449                         /*                    << 
1450                          * We've replaced the << 
1451                          * insn: RET; INT3, e << 
1452                          * insn here. Mark it << 
1453                          * warning, instead o << 
1454                          */                   << 
1455                         insn->retpoline_safe  << 
1456                 }                             << 
1457                                               << 
1458                 return;                       << 
1459         }                                     << 
1460                                               << 
1461         if (opts.mcount && sym->fentry) {     << 
1462                 if (sibling)                  << 
1463                         WARN_INSN(insn, "tail << 
1464                 if (opts.mnop) {              << 
1465                         if (reloc)            << 
1466                                 set_reloc_typ << 
1467                                               << 
1468                         elf_write_insn(file-> << 
1469                                        insn-> << 
1470                                        arch_n << 
1471                                               << 
1472                         insn->type = INSN_NOP << 
1473                 }                             << 
1474                                               << 
1475                 list_add_tail(&insn->call_nod << 
1476                 return;                       << 
1477         }                                     << 
1478                                               << 
1479         if (insn->type == INSN_CALL && !insn- << 
1480                 list_add_tail(&insn->call_nod << 
1481                                               << 
1482         if (!sibling && dead_end_function(fil << 
1483                 insn->dead_end = true;        << 
1484 }                                             << 
1485                                               << 
1486 static void add_call_dest(struct objtool_file << 
1487                           struct symbol *dest << 
1488 {                                             << 
1489         insn->_call_dest = dest;              << 
1490         if (!dest)                            << 
1491                 return;                       << 
1492                                               << 
1493         /*                                    << 
1494          * Whatever stack impact regular CALL << 
1495          * by the RETURN of the called functi << 
1496          *                                    << 
1497          * Annotated intra-function calls ret << 
1498          * are converted to JUMP, see read_in << 
1499          */                                   << 
1500         remove_insn_ops(insn);                << 
1501                                               << 
1502         annotate_call_site(file, insn, siblin << 
1503 }                                             << 
1504                                               << 
1505 static void add_retpoline_call(struct objtool << 
1506 {                                             << 
1507         /*                                    << 
1508          * Retpoline calls/jumps are really d << 
1509          * so convert them accordingly.       << 
1510          */                                   << 
1511         switch (insn->type) {                 << 
1512         case INSN_CALL:                       << 
1513                 insn->type = INSN_CALL_DYNAMI << 
1514                 break;                        << 
1515         case INSN_JUMP_UNCONDITIONAL:         << 
1516                 insn->type = INSN_JUMP_DYNAMI << 
1517                 break;                        << 
1518         case INSN_JUMP_CONDITIONAL:           << 
1519                 insn->type = INSN_JUMP_DYNAMI << 
1520                 break;                        << 
1521         default:                              << 
1522                 return;                       << 
1523         }                                     << 
1524                                               << 
1525         insn->retpoline_safe = true;          << 
1526                                               << 
1527         /*                                    << 
1528          * Whatever stack impact regular CALL << 
1529          * by the RETURN of the called functi << 
1530          *                                    << 
1531          * Annotated intra-function calls ret << 
1532          * are converted to JUMP, see read_in << 
1533          */                                   << 
1534         remove_insn_ops(insn);                << 
1535                                               << 
1536         annotate_call_site(file, insn, false) << 
1537 }                                             << 
1538                                               << 
1539 static void add_return_call(struct objtool_fi << 
1540 {                                             << 
1541         /*                                    << 
1542          * Return thunk tail calls are really << 
1543          * so convert them accordingly.       << 
1544          */                                   << 
1545         insn->type = INSN_RETURN;             << 
1546         insn->retpoline_safe = true;          << 
1547                                               << 
1548         if (add)                              << 
1549                 list_add_tail(&insn->call_nod << 
1550 }                                             << 
1551                                               << 
1552 static bool is_first_func_insn(struct objtool << 
1553                                struct instruc << 
1554 {                                             << 
1555         if (insn->offset == sym->offset)      << 
1556                 return true;                  << 
1557                                               << 
1558         /* Allow direct CALL/JMP past ENDBR * << 
1559         if (opts.ibt) {                       << 
1560                 struct instruction *prev = pr << 
1561                                               << 
1562                 if (prev && prev->type == INS << 
1563                     insn->offset == sym->offs << 
1564                         return true;          << 
1565         }                                     << 
1566                                               << 
1567         return false;                         << 
1568 }                                             << 
1569                                               << 
1570 /*                                            << 
1571  * A sibling call is a tail-call to another s << 
1572  * recursive tail-call which is to the same s << 
1573  */                                           << 
1574 static bool jump_is_sibling_call(struct objto << 
1575                                  struct instr << 
1576 {                                             << 
1577         struct symbol *fs = from->sym;        << 
1578         struct symbol *ts = to->sym;          << 
1579                                               << 
1580         /* Not a sibling call if from/to a sy << 
1581         if (!fs || !ts)                       << 
1582                 return false;                 << 
1583                                               << 
1584         /* Not a sibling call if not targetin << 
1585         if (!is_first_func_insn(file, to, ts) << 
1586                 return false;                 << 
1587                                               << 
1588         /* Disallow sibling calls into STT_NO << 
1589         if (ts->type == STT_NOTYPE)           << 
1590                 return false;                 << 
1591                                               << 
1592         /* Must not be self to be a sibling * << 
1593         return fs->pfunc != ts->pfunc;        << 
1594 }                                             << 
1595                                               << 
1596 /*                                            << 
1597  * Find the destination instructions for all     465  * Find the destination instructions for all jumps.
1598  */                                              466  */
1599 static int add_jump_destinations(struct objto    467 static int add_jump_destinations(struct objtool_file *file)
1600 {                                                468 {
1601         struct instruction *insn, *jump_dest; !! 469         struct instruction *insn;
1602         struct reloc *reloc;                  !! 470         struct rela *rela;
1603         struct section *dest_sec;                471         struct section *dest_sec;
1604         unsigned long dest_off;                  472         unsigned long dest_off;
1605                                                  473 
1606         for_each_insn(file, insn) {              474         for_each_insn(file, insn) {
1607                 if (insn->jump_dest) {        !! 475                 if (insn->type != INSN_JUMP_CONDITIONAL &&
1608                         /*                    !! 476                     insn->type != INSN_JUMP_UNCONDITIONAL)
1609                          * handle_group_alt() << 
1610                          * 'jump_dest' for so << 
1611                          */                   << 
1612                         continue;                477                         continue;
1613                 }                             !! 478 
1614                 if (!is_static_jump(insn))    !! 479                 if (insn->ignore)
1615                         continue;                480                         continue;
1616                                                  481 
1617                 reloc = insn_reloc(file, insn !! 482                 rela = find_rela_by_dest_range(insn->sec, insn->offset,
1618                 if (!reloc) {                 !! 483                                                insn->len);
                                                   >> 484                 if (!rela) {
1619                         dest_sec = insn->sec;    485                         dest_sec = insn->sec;
1620                         dest_off = arch_jump_ !! 486                         dest_off = insn->offset + insn->len + insn->immediate;
1621                 } else if (reloc->sym->type = !! 487                 } else if (rela->sym->type == STT_SECTION) {
1622                         dest_sec = reloc->sym !! 488                         dest_sec = rela->sym->sec;
1623                         dest_off = arch_dest_ !! 489                         dest_off = rela->addend + 4;
1624                 } else if (reloc->sym->retpol !! 490                 } else if (rela->sym->sec->idx) {
1625                         add_retpoline_call(fi !! 491                         dest_sec = rela->sym->sec;
1626                         continue;             !! 492                         dest_off = rela->sym->sym.st_value + rela->addend + 4;
1627                 } else if (reloc->sym->return !! 493                 } else if (strstr(rela->sym->name, "_indirect_thunk_")) {
1628                         add_return_call(file, << 
1629                         continue;             << 
1630                 } else if (insn_func(insn)) { << 
1631                         /*                       494                         /*
1632                          * External sibling c !! 495                          * Retpoline jumps are really dynamic jumps in
1633                          * STT_FUNC reloc.    !! 496                          * disguise, so convert them accordingly.
1634                          */                      497                          */
1635                         add_call_dest(file, i !! 498                         insn->type = INSN_JUMP_DYNAMIC;
                                                   >> 499                         insn->retpoline_safe = true;
1636                         continue;                500                         continue;
1637                 } else if (reloc->sym->sec->i << 
1638                         dest_sec = reloc->sym << 
1639                         dest_off = reloc->sym << 
1640                                    arch_dest_ << 
1641                 } else {                         501                 } else {
1642                         /* non-func asm code  !! 502                         /* sibling call */
                                                   >> 503                         insn->jump_dest = 0;
1643                         continue;                504                         continue;
1644                 }                                505                 }
1645                                                  506 
1646                 jump_dest = find_insn(file, d !! 507                 insn->jump_dest = find_insn(file, dest_sec, dest_off);
1647                 if (!jump_dest) {             !! 508                 if (!insn->jump_dest) {
1648                         struct symbol *sym =  << 
1649                                                  509 
1650                         /*                       510                         /*
1651                          * This is a special  !! 511                          * This is a special case where an alt instruction
1652                          * It jumps to __x86_ !! 512                          * jumps past the end of the section.  These are
1653                          * can't find the thu !! 513                          * handled later in handle_group_alt().
1654                          * instruction, becau << 
1655                          * middle of another  << 
1656                          * knows about the ou << 
1657                          */                      514                          */
1658                         if (sym && sym->embed !! 515                         if (!strcmp(insn->sec->name, ".altinstr_replacement"))
1659                                 add_return_ca << 
1660                                 continue;        516                                 continue;
1661                         }                     << 
1662                                                  517 
1663                         WARN_INSN(insn, "can' !! 518                         WARN_FUNC("can't find jump dest instruction at %s+0x%lx",
1664                                   dest_sec->n !! 519                                   insn->sec, insn->offset, dest_sec->name,
                                                   >> 520                                   dest_off);
1665                         return -1;               521                         return -1;
1666                 }                                522                 }
1667                                               << 
1668                 /*                            << 
1669                  * An intra-TU jump in retpol << 
1670                  * for its jump dest, in whic << 
1671                  * add_{retpoline,return}_cal << 
1672                  */                           << 
1673                 if (jump_dest->sym && jump_de << 
1674                         if (jump_dest->sym->r << 
1675                                 add_retpoline << 
1676                                 continue;     << 
1677                         }                     << 
1678                         if (jump_dest->sym->r << 
1679                                 add_return_ca << 
1680                                 continue;     << 
1681                         }                     << 
1682                 }                             << 
1683                                               << 
1684                 /*                            << 
1685                  * Cross-function jump.       << 
1686                  */                           << 
1687                 if (insn_func(insn) && insn_f << 
1688                     insn_func(insn) != insn_f << 
1689                                               << 
1690                         /*                    << 
1691                          * For GCC 8+, create << 
1692                          * subfunctions.  Thi << 
1693                          * similar initializa << 
1694                          *                    << 
1695                          * If a function has  << 
1696                          * function in the sy << 
1697                          * parent.  In that c << 
1698                          * initialization don << 
1699                          *                    << 
1700                          * However this code  << 
1701                          * read_symbols() cod << 
1702                          * case where the par << 
1703                          * subfunction is thr << 
1704                          */                   << 
1705                         if (!strstr(insn_func << 
1706                             strstr(insn_func( << 
1707                                 insn_func(ins << 
1708                                 insn_func(jum << 
1709                         }                     << 
1710                 }                             << 
1711                                               << 
1712                 if (jump_is_sibling_call(file << 
1713                         /*                    << 
1714                          * Internal sibling c << 
1715                          * STT_SECTION reloc. << 
1716                          */                   << 
1717                         add_call_dest(file, i << 
1718                         continue;             << 
1719                 }                             << 
1720                                               << 
1721                 insn->jump_dest = jump_dest;  << 
1722         }                                        523         }
1723                                                  524 
1724         return 0;                                525         return 0;
1725 }                                                526 }
1726                                                  527 
1727 static struct symbol *find_call_destination(s << 
1728 {                                             << 
1729         struct symbol *call_dest;             << 
1730                                               << 
1731         call_dest = find_func_by_offset(sec,  << 
1732         if (!call_dest)                       << 
1733                 call_dest = find_symbol_by_of << 
1734                                               << 
1735         return call_dest;                     << 
1736 }                                             << 
1737                                               << 
1738 /*                                               528 /*
1739  * Find the destination instructions for all     529  * Find the destination instructions for all calls.
1740  */                                              530  */
1741 static int add_call_destinations(struct objto    531 static int add_call_destinations(struct objtool_file *file)
1742 {                                                532 {
1743         struct instruction *insn;                533         struct instruction *insn;
1744         unsigned long dest_off;                  534         unsigned long dest_off;
1745         struct symbol *dest;                  !! 535         struct rela *rela;
1746         struct reloc *reloc;                  << 
1747                                                  536 
1748         for_each_insn(file, insn) {              537         for_each_insn(file, insn) {
1749                 if (insn->type != INSN_CALL)     538                 if (insn->type != INSN_CALL)
1750                         continue;                539                         continue;
1751                                                  540 
1752                 reloc = insn_reloc(file, insn !! 541                 rela = find_rela_by_dest_range(insn->sec, insn->offset,
1753                 if (!reloc) {                 !! 542                                                insn->len);
1754                         dest_off = arch_jump_ !! 543                 if (!rela) {
1755                         dest = find_call_dest !! 544                         dest_off = insn->offset + insn->len + insn->immediate;
1756                                               !! 545                         insn->call_dest = find_symbol_by_offset(insn->sec,
1757                         add_call_dest(file, i !! 546                                                                 dest_off);
1758                                               !! 547 
1759                         if (insn->ignore)     !! 548                         if (!insn->call_dest && !insn->ignore) {
1760                                 continue;     !! 549                                 WARN_FUNC("unsupported intra-function call",
1761                                               !! 550                                           insn->sec, insn->offset);
1762                         if (!insn_call_dest(i !! 551                                 if (retpoline)
1763                                 WARN_INSN(ins !! 552                                         WARN("If this is a retpoline, please patch it in with alternatives and annotate it with ANNOTATE_NOSPEC_ALTERNATIVE.");
1764                                 return -1;    << 
1765                         }                     << 
1766                                               << 
1767                         if (insn_func(insn) & << 
1768                                 WARN_INSN(ins << 
1769                                 return -1;       553                                 return -1;
1770                         }                        554                         }
1771                                                  555 
1772                 } else if (reloc->sym->type = !! 556                 } else if (rela->sym->type == STT_SECTION) {
1773                         dest_off = arch_dest_ !! 557                         insn->call_dest = find_symbol_by_offset(rela->sym->sec,
1774                         dest = find_call_dest !! 558                                                                 rela->addend+4);
1775                         if (!dest) {          !! 559                         if (!insn->call_dest ||
1776                                 WARN_INSN(ins !! 560                             insn->call_dest->type != STT_FUNC) {
1777                                           rel !! 561                                 WARN_FUNC("can't find call dest symbol at %s+0x%x",
                                                   >> 562                                           insn->sec, insn->offset,
                                                   >> 563                                           rela->sym->sec->name,
                                                   >> 564                                           rela->addend + 4);
1778                                 return -1;       565                                 return -1;
1779                         }                        566                         }
1780                                               << 
1781                         add_call_dest(file, i << 
1782                                               << 
1783                 } else if (reloc->sym->retpol << 
1784                         add_retpoline_call(fi << 
1785                                               << 
1786                 } else                           567                 } else
1787                         add_call_dest(file, i !! 568                         insn->call_dest = rela->sym;
1788         }                                        569         }
1789                                                  570 
1790         return 0;                                571         return 0;
1791 }                                                572 }
1792                                                  573 
1793 /*                                               574 /*
1794  * The .alternatives section requires some ex !! 575  * The .alternatives section requires some extra special care, over and above
1795  * other special sections because alternative !! 576  * what other special sections require:
                                                   >> 577  *
                                                   >> 578  * 1. Because alternatives are patched in-place, we need to insert a fake jump
                                                   >> 579  *    instruction at the end so that validate_branch() skips all the original
                                                   >> 580  *    replaced instructions when validating the new instruction path.
                                                   >> 581  *
                                                   >> 582  * 2. An added wrinkle is that the new instruction length might be zero.  In
                                                   >> 583  *    that case the old instructions are replaced with noops.  We simulate that
                                                   >> 584  *    by creating a fake jump as the only new instruction.
                                                   >> 585  *
                                                   >> 586  * 3. In some cases, the alternative section includes an instruction which
                                                   >> 587  *    conditionally jumps to the _end_ of the entry.  We have to modify these
                                                   >> 588  *    jumps' destinations to point back to .text rather than the end of the
                                                   >> 589  *    entry in .altinstr_replacement.
                                                   >> 590  *
                                                   >> 591  * 4. It has been requested that we don't validate the !POPCNT feature path
                                                   >> 592  *    which is a "very very small percentage of machines".
1796  */                                              593  */
1797 static int handle_group_alt(struct objtool_fi    594 static int handle_group_alt(struct objtool_file *file,
1798                             struct special_al    595                             struct special_alt *special_alt,
1799                             struct instructio    596                             struct instruction *orig_insn,
1800                             struct instructio    597                             struct instruction **new_insn)
1801 {                                                598 {
1802         struct instruction *last_new_insn = N !! 599         struct instruction *last_orig_insn, *last_new_insn, *insn, *fake_jump = NULL;
1803         struct alt_group *orig_alt_group, *ne << 
1804         unsigned long dest_off;                  600         unsigned long dest_off;
1805                                                  601 
1806         orig_alt_group = orig_insn->alt_group !! 602         last_orig_insn = NULL;
1807         if (!orig_alt_group) {                !! 603         insn = orig_insn;
1808                 struct instruction *last_orig !! 604         sec_for_each_insn_from(file, insn) {
1809                                               !! 605                 if (insn->offset >= special_alt->orig_off + special_alt->orig_len)
1810                 orig_alt_group = malloc(sizeo !! 606                         break;
1811                 if (!orig_alt_group) {        << 
1812                         WARN("malloc failed") << 
1813                         return -1;            << 
1814                 }                             << 
1815                 orig_alt_group->cfi = calloc( << 
1816                                               << 
1817                 if (!orig_alt_group->cfi) {   << 
1818                         WARN("calloc failed") << 
1819                         return -1;            << 
1820                 }                             << 
1821                                               << 
1822                 insn = orig_insn;             << 
1823                 sec_for_each_insn_from(file,  << 
1824                         if (insn->offset >= s << 
1825                                 break;        << 
1826                                                  607 
1827                         insn->alt_group = ori !! 608                 if (special_alt->skip_orig)
1828                         last_orig_insn = insn !! 609                         insn->type = INSN_NOP;
1829                 }                             << 
1830                 orig_alt_group->orig_group =  << 
1831                 orig_alt_group->first_insn =  << 
1832                 orig_alt_group->last_insn = l << 
1833                 orig_alt_group->nop = NULL;   << 
1834         } else {                              << 
1835                 if (orig_alt_group->last_insn << 
1836                     orig_alt_group->first_ins << 
1837                         WARN_INSN(orig_insn,  << 
1838                                   orig_alt_gr << 
1839                                   orig_alt_gr << 
1840                                   orig_alt_gr << 
1841                                   special_alt << 
1842                         return -1;            << 
1843                 }                             << 
1844         }                                     << 
1845                                                  610 
1846         new_alt_group = malloc(sizeof(*new_al !! 611                 insn->alt_group = true;
1847         if (!new_alt_group) {                 !! 612                 last_orig_insn = insn;
1848                 WARN("malloc failed");        << 
1849                 return -1;                    << 
1850         }                                        613         }
1851                                                  614 
1852         if (special_alt->new_len < special_al !! 615         if (next_insn_same_sec(file, last_orig_insn)) {
1853                 /*                            !! 616                 fake_jump = malloc(sizeof(*fake_jump));
1854                  * Insert a fake nop at the e !! 617                 if (!fake_jump) {
1855                  * alt_group the same size as << 
1856                  * allow propagate_alt_cfi()  << 
1857                  * instruction affects the st << 
1858                  * nop) will propagate the ne << 
1859                  */                           << 
1860                 nop = malloc(sizeof(*nop));   << 
1861                 if (!nop) {                   << 
1862                         WARN("malloc failed")    618                         WARN("malloc failed");
1863                         return -1;               619                         return -1;
1864                 }                                620                 }
1865                 memset(nop, 0, sizeof(*nop)); !! 621                 memset(fake_jump, 0, sizeof(*fake_jump));
1866                                               !! 622                 INIT_LIST_HEAD(&fake_jump->alts);
1867                 nop->sec = special_alt->new_s !! 623                 clear_insn_state(&fake_jump->state);
1868                 nop->offset = special_alt->ne !! 624 
1869                 nop->len = special_alt->orig_ !! 625                 fake_jump->sec = special_alt->new_sec;
1870                 nop->type = INSN_NOP;         !! 626                 fake_jump->offset = -1;
1871                 nop->sym = orig_insn->sym;    !! 627                 fake_jump->type = INSN_JUMP_UNCONDITIONAL;
1872                 nop->alt_group = new_alt_grou !! 628                 fake_jump->jump_dest = list_next_entry(last_orig_insn, list);
1873                 nop->ignore = orig_insn->igno !! 629                 fake_jump->ignore = true;
1874         }                                        630         }
1875                                                  631 
1876         if (!special_alt->new_len) {             632         if (!special_alt->new_len) {
1877                 *new_insn = nop;              !! 633                 if (!fake_jump) {
1878                 goto end;                     !! 634                         WARN("%s: empty alternative at end of section",
                                                   >> 635                              special_alt->orig_sec->name);
                                                   >> 636                         return -1;
                                                   >> 637                 }
                                                   >> 638 
                                                   >> 639                 *new_insn = fake_jump;
                                                   >> 640                 return 0;
1879         }                                        641         }
1880                                                  642 
                                                   >> 643         last_new_insn = NULL;
1881         insn = *new_insn;                        644         insn = *new_insn;
1882         sec_for_each_insn_from(file, insn) {     645         sec_for_each_insn_from(file, insn) {
1883                 struct reloc *alt_reloc;      << 
1884                                               << 
1885                 if (insn->offset >= special_a    646                 if (insn->offset >= special_alt->new_off + special_alt->new_len)
1886                         break;                   647                         break;
1887                                                  648 
1888                 last_new_insn = insn;            649                 last_new_insn = insn;
1889                                                  650 
1890                 insn->ignore = orig_insn->ign    651                 insn->ignore = orig_insn->ignore_alts;
1891                 insn->sym = orig_insn->sym;   << 
1892                 insn->alt_group = new_alt_gro << 
1893                                                  652 
1894                 /*                            !! 653                 if (insn->type != INSN_JUMP_CONDITIONAL &&
1895                  * Since alternative replacem !! 654                     insn->type != INSN_JUMP_UNCONDITIONAL)
1896                  * kernel after applying relo << 
1897                  * have relative-address relo << 
1898                  * .altinstr_replacement sect << 
1899                  * alternatives code can adju << 
1900                  * accordingly.               << 
1901                  */                           << 
1902                 alt_reloc = insn_reloc(file,  << 
1903                 if (alt_reloc && arch_pc_rela << 
1904                     !arch_support_alt_relocat << 
1905                                               << 
1906                         WARN_INSN(insn, "unsu << 
1907                         return -1;            << 
1908                 }                             << 
1909                                               << 
1910                 if (!is_static_jump(insn))    << 
1911                         continue;                655                         continue;
1912                                                  656 
1913                 if (!insn->immediate)            657                 if (!insn->immediate)
1914                         continue;                658                         continue;
1915                                                  659 
1916                 dest_off = arch_jump_destinat !! 660                 dest_off = insn->offset + insn->len + insn->immediate;
1917                 if (dest_off == special_alt->    661                 if (dest_off == special_alt->new_off + special_alt->new_len) {
1918                         insn->jump_dest = nex !! 662                         if (!fake_jump) {
1919                         if (!insn->jump_dest) !! 663                                 WARN("%s: alternative jump to end of section",
1920                                 WARN_INSN(ins !! 664                                      special_alt->orig_sec->name);
1921                                 return -1;       665                                 return -1;
1922                         }                        666                         }
                                                   >> 667                         insn->jump_dest = fake_jump;
                                                   >> 668                 }
                                                   >> 669 
                                                   >> 670                 if (!insn->jump_dest) {
                                                   >> 671                         WARN_FUNC("can't find alternative jump destination",
                                                   >> 672                                   insn->sec, insn->offset);
                                                   >> 673                         return -1;
1923                 }                                674                 }
1924         }                                        675         }
1925                                                  676 
1926         if (!last_new_insn) {                    677         if (!last_new_insn) {
1927                 WARN_FUNC("can't find last ne    678                 WARN_FUNC("can't find last new alternative instruction",
1928                           special_alt->new_se    679                           special_alt->new_sec, special_alt->new_off);
1929                 return -1;                       680                 return -1;
1930         }                                        681         }
1931                                                  682 
1932 end:                                          !! 683         if (fake_jump)
1933         new_alt_group->orig_group = orig_alt_ !! 684                 list_add(&fake_jump->list, &last_new_insn->list);
1934         new_alt_group->first_insn = *new_insn !! 685 
1935         new_alt_group->last_insn = last_new_i << 
1936         new_alt_group->nop = nop;             << 
1937         new_alt_group->cfi = orig_alt_group-> << 
1938         return 0;                                686         return 0;
1939 }                                                687 }
1940                                                  688 
1941 /*                                               689 /*
1942  * A jump table entry can either convert a no    690  * A jump table entry can either convert a nop to a jump or a jump to a nop.
1943  * If the original instruction is a jump, mak    691  * If the original instruction is a jump, make the alt entry an effective nop
1944  * by just skipping the original instruction.    692  * by just skipping the original instruction.
1945  */                                              693  */
1946 static int handle_jump_alt(struct objtool_fil    694 static int handle_jump_alt(struct objtool_file *file,
1947                            struct special_alt    695                            struct special_alt *special_alt,
1948                            struct instruction    696                            struct instruction *orig_insn,
1949                            struct instruction    697                            struct instruction **new_insn)
1950 {                                                698 {
1951         if (orig_insn->type != INSN_JUMP_UNCO !! 699         if (orig_insn->type == INSN_NOP)
1952             orig_insn->type != INSN_NOP) {    !! 700                 return 0;
1953                                                  701 
1954                 WARN_INSN(orig_insn, "unsuppo !! 702         if (orig_insn->type != INSN_JUMP_UNCONDITIONAL) {
                                                   >> 703                 WARN_FUNC("unsupported instruction at jump label",
                                                   >> 704                           orig_insn->sec, orig_insn->offset);
1955                 return -1;                       705                 return -1;
1956         }                                        706         }
1957                                                  707 
1958         if (opts.hack_jump_label && special_a !! 708         *new_insn = list_next_entry(orig_insn, list);
1959                 struct reloc *reloc = insn_re << 
1960                                               << 
1961                 if (reloc)                    << 
1962                         set_reloc_type(file-> << 
1963                 elf_write_insn(file->elf, ori << 
1964                                orig_insn->off << 
1965                                arch_nop_insn( << 
1966                 orig_insn->type = INSN_NOP;   << 
1967         }                                     << 
1968                                               << 
1969         if (orig_insn->type == INSN_NOP) {    << 
1970                 if (orig_insn->len == 2)      << 
1971                         file->jl_nop_short++; << 
1972                 else                          << 
1973                         file->jl_nop_long++;  << 
1974                                               << 
1975                 return 0;                     << 
1976         }                                     << 
1977                                               << 
1978         if (orig_insn->len == 2)              << 
1979                 file->jl_short++;             << 
1980         else                                  << 
1981                 file->jl_long++;              << 
1982                                               << 
1983         *new_insn = next_insn_same_sec(file,  << 
1984         return 0;                                709         return 0;
1985 }                                                710 }
1986                                                  711 
1987 /*                                               712 /*
1988  * Read all the special sections which have a    713  * Read all the special sections which have alternate instructions which can be
1989  * patched in or redirected to at runtime.  E    714  * patched in or redirected to at runtime.  Each instruction having alternate
1990  * instruction(s) has them added to its insn-    715  * instruction(s) has them added to its insn->alts list, which will be
1991  * traversed in validate_branch().               716  * traversed in validate_branch().
1992  */                                              717  */
1993 static int add_special_section_alts(struct ob    718 static int add_special_section_alts(struct objtool_file *file)
1994 {                                                719 {
1995         struct list_head special_alts;           720         struct list_head special_alts;
1996         struct instruction *orig_insn, *new_i    721         struct instruction *orig_insn, *new_insn;
1997         struct special_alt *special_alt, *tmp    722         struct special_alt *special_alt, *tmp;
1998         struct alternative *alt;                 723         struct alternative *alt;
1999         int ret;                                 724         int ret;
2000                                                  725 
2001         ret = special_get_alts(file->elf, &sp    726         ret = special_get_alts(file->elf, &special_alts);
2002         if (ret)                                 727         if (ret)
2003                 return ret;                      728                 return ret;
2004                                                  729 
2005         list_for_each_entry_safe(special_alt,    730         list_for_each_entry_safe(special_alt, tmp, &special_alts, list) {
2006                                                  731 
2007                 orig_insn = find_insn(file, s    732                 orig_insn = find_insn(file, special_alt->orig_sec,
2008                                       special    733                                       special_alt->orig_off);
2009                 if (!orig_insn) {                734                 if (!orig_insn) {
2010                         WARN_FUNC("special: c    735                         WARN_FUNC("special: can't find orig instruction",
2011                                   special_alt    736                                   special_alt->orig_sec, special_alt->orig_off);
2012                         ret = -1;                737                         ret = -1;
2013                         goto out;                738                         goto out;
2014                 }                                739                 }
2015                                                  740 
2016                 new_insn = NULL;                 741                 new_insn = NULL;
2017                 if (!special_alt->group || sp    742                 if (!special_alt->group || special_alt->new_len) {
2018                         new_insn = find_insn(    743                         new_insn = find_insn(file, special_alt->new_sec,
2019                                                  744                                              special_alt->new_off);
2020                         if (!new_insn) {         745                         if (!new_insn) {
2021                                 WARN_FUNC("sp    746                                 WARN_FUNC("special: can't find new instruction",
2022                                           spe    747                                           special_alt->new_sec,
2023                                           spe    748                                           special_alt->new_off);
2024                                 ret = -1;        749                                 ret = -1;
2025                                 goto out;        750                                 goto out;
2026                         }                        751                         }
2027                 }                                752                 }
2028                                                  753 
2029                 if (special_alt->group) {        754                 if (special_alt->group) {
2030                         if (!special_alt->ori << 
2031                                 WARN_INSN(ori << 
2032                                 continue;     << 
2033                         }                     << 
2034                                               << 
2035                         ret = handle_group_al    755                         ret = handle_group_alt(file, special_alt, orig_insn,
2036                                                  756                                                &new_insn);
2037                         if (ret)                 757                         if (ret)
2038                                 goto out;        758                                 goto out;
2039                 } else if (special_alt->jump_    759                 } else if (special_alt->jump_or_nop) {
2040                         ret = handle_jump_alt    760                         ret = handle_jump_alt(file, special_alt, orig_insn,
2041                                                  761                                               &new_insn);
2042                         if (ret)                 762                         if (ret)
2043                                 goto out;        763                                 goto out;
2044                 }                                764                 }
2045                                                  765 
2046                 alt = malloc(sizeof(*alt));      766                 alt = malloc(sizeof(*alt));
2047                 if (!alt) {                      767                 if (!alt) {
2048                         WARN("malloc failed")    768                         WARN("malloc failed");
2049                         ret = -1;                769                         ret = -1;
2050                         goto out;                770                         goto out;
2051                 }                                771                 }
2052                                                  772 
2053                 alt->insn = new_insn;            773                 alt->insn = new_insn;
2054                 alt->skip_orig = special_alt- !! 774                 list_add_tail(&alt->list, &orig_insn->alts);
2055                 orig_insn->ignore_alts |= spe << 
2056                 alt->next = orig_insn->alts;  << 
2057                 orig_insn->alts = alt;        << 
2058                                                  775 
2059                 list_del(&special_alt->list);    776                 list_del(&special_alt->list);
2060                 free(special_alt);               777                 free(special_alt);
2061         }                                        778         }
2062                                                  779 
2063         if (opts.stats) {                     << 
2064                 printf("jl\\\tNOP\tJMP\n");   << 
2065                 printf("short:\t%ld\t%ld\n",  << 
2066                 printf("long:\t%ld\t%ld\n", f << 
2067         }                                     << 
2068                                               << 
2069 out:                                             780 out:
2070         return ret;                              781         return ret;
2071 }                                                782 }
2072                                                  783 
2073 static int add_jump_table(struct objtool_file !! 784 static int add_switch_table(struct objtool_file *file, struct symbol *func,
2074                           struct reloc *next_ !! 785                             struct instruction *insn, struct rela *table,
                                                   >> 786                             struct rela *next_table)
2075 {                                                787 {
2076         struct symbol *pfunc = insn_func(insn !! 788         struct rela *rela = table;
2077         struct reloc *table = insn_jump_table !! 789         struct instruction *alt_insn;
2078         struct instruction *dest_insn;        << 
2079         unsigned int prev_offset = 0;         << 
2080         struct reloc *reloc = table;          << 
2081         struct alternative *alt;                 790         struct alternative *alt;
2082                                                  791 
2083         /*                                    !! 792         list_for_each_entry_from(rela, &file->rodata->rela->rela_list, list) {
2084          * Each @reloc is a switch table relo !! 793                 if (rela == next_table)
2085          * instruction.                       << 
2086          */                                   << 
2087         for_each_reloc_from(table->sec, reloc << 
2088                                               << 
2089                 /* Check for the end of the t << 
2090                 if (reloc != table && reloc = << 
2091                         break;                << 
2092                                               << 
2093                 /* Make sure the table entrie << 
2094                 if (prev_offset && reloc_offs << 
2095                         break;                   794                         break;
2096                                                  795 
2097                 /* Detect function pointers f !! 796                 if (rela->sym->sec != insn->sec ||
2098                 if (reloc->sym->sec == pfunc- !! 797                     rela->addend <= func->offset ||
2099                     reloc_addend(reloc) == pf !! 798                     rela->addend >= func->offset + func->len)
2100                         break;                   799                         break;
2101                                                  800 
2102                 dest_insn = find_insn(file, r !! 801                 alt_insn = find_insn(file, insn->sec, rela->addend);
2103                 if (!dest_insn)               !! 802                 if (!alt_insn) {
2104                         break;                !! 803                         WARN("%s: can't find instruction at %s+0x%x",
2105                                               !! 804                              file->rodata->rela->name, insn->sec->name,
2106                 /* Make sure the destination  !! 805                              rela->addend);
2107                 if (!insn_func(dest_insn) ||  !! 806                         return -1;
2108                         break;                !! 807                 }
2109                                                  808 
2110                 alt = malloc(sizeof(*alt));      809                 alt = malloc(sizeof(*alt));
2111                 if (!alt) {                      810                 if (!alt) {
2112                         WARN("malloc failed")    811                         WARN("malloc failed");
2113                         return -1;               812                         return -1;
2114                 }                                813                 }
2115                                                  814 
2116                 alt->insn = dest_insn;        !! 815                 alt->insn = alt_insn;
2117                 alt->next = insn->alts;       !! 816                 list_add_tail(&alt->list, &insn->alts);
2118                 insn->alts = alt;             << 
2119                 prev_offset = reloc_offset(re << 
2120         }                                     << 
2121                                               << 
2122         if (!prev_offset) {                   << 
2123                 WARN_INSN(insn, "can't find s << 
2124                 return -1;                    << 
2125         }                                        817         }
2126                                                  818 
2127         return 0;                                819         return 0;
2128 }                                                820 }
2129                                                  821 
2130 /*                                               822 /*
2131  * find_jump_table() - Given a dynamic jump,  !! 823  * find_switch_table() - Given a dynamic jump, find the switch jump table in
2132  * associated with it.                        !! 824  * .rodata associated with it.
                                                   >> 825  *
                                                   >> 826  * There are 3 basic patterns:
                                                   >> 827  *
                                                   >> 828  * 1. jmpq *[rodata addr](,%reg,8)
                                                   >> 829  *
                                                   >> 830  *    This is the most common case by far.  It jumps to an address in a simple
                                                   >> 831  *    jump table which is stored in .rodata.
                                                   >> 832  *
                                                   >> 833  * 2. jmpq *[rodata addr](%rip)
                                                   >> 834  *
                                                   >> 835  *    This is caused by a rare GCC quirk, currently only seen in three driver
                                                   >> 836  *    functions in the kernel, only with certain obscure non-distro configs.
                                                   >> 837  *
                                                   >> 838  *    As part of an optimization, GCC makes a copy of an existing switch jump
                                                   >> 839  *    table, modifies it, and then hard-codes the jump (albeit with an indirect
                                                   >> 840  *    jump) to use a single entry in the table.  The rest of the jump table and
                                                   >> 841  *    some of its jump targets remain as dead code.
                                                   >> 842  *
                                                   >> 843  *    In such a case we can just crudely ignore all unreachable instruction
                                                   >> 844  *    warnings for the entire object file.  Ideally we would just ignore them
                                                   >> 845  *    for the function, but that would require redesigning the code quite a
                                                   >> 846  *    bit.  And honestly that's just not worth doing: unreachable instruction
                                                   >> 847  *    warnings are of questionable value anyway, and this is such a rare issue.
                                                   >> 848  *
                                                   >> 849  * 3. mov [rodata addr],%reg1
                                                   >> 850  *    ... some instructions ...
                                                   >> 851  *    jmpq *(%reg1,%reg2,8)
                                                   >> 852  *
                                                   >> 853  *    This is a fairly uncommon pattern which is new for GCC 6.  As of this
                                                   >> 854  *    writing, there are 11 occurrences of it in the allmodconfig kernel.
                                                   >> 855  *
                                                   >> 856  *    As of GCC 7 there are quite a few more of these and the 'in between' code
                                                   >> 857  *    is significant. Esp. with KASAN enabled some of the code between the mov
                                                   >> 858  *    and jmpq uses .rodata itself, which can confuse things.
                                                   >> 859  *
                                                   >> 860  *    TODO: Once we have DWARF CFI and smarter instruction decoding logic,
                                                   >> 861  *    ensure the same register is used in the mov and jump instructions.
                                                   >> 862  *
                                                   >> 863  *    NOTE: RETPOLINE made it harder still to decode dynamic jumps.
2133  */                                              864  */
2134 static struct reloc *find_jump_table(struct o !! 865 static struct rela *find_switch_table(struct objtool_file *file,
2135                                       struct     866                                       struct symbol *func,
2136                                       struct     867                                       struct instruction *insn)
2137 {                                                868 {
2138         struct reloc *table_reloc;            !! 869         struct rela *text_rela, *rodata_rela;
2139         struct instruction *dest_insn, *orig_ !! 870         struct instruction *orig_insn = insn;
                                                   >> 871 
                                                   >> 872         text_rela = find_rela_by_dest_range(insn->sec, insn->offset, insn->len);
                                                   >> 873         if (text_rela && text_rela->sym == file->rodata->sym) {
                                                   >> 874                 /* case 1 */
                                                   >> 875                 rodata_rela = find_rela_by_dest(file->rodata,
                                                   >> 876                                                 text_rela->addend);
                                                   >> 877                 if (rodata_rela)
                                                   >> 878                         return rodata_rela;
                                                   >> 879 
                                                   >> 880                 /* case 2 */
                                                   >> 881                 rodata_rela = find_rela_by_dest(file->rodata,
                                                   >> 882                                                 text_rela->addend + 4);
                                                   >> 883                 if (!rodata_rela)
                                                   >> 884                         return NULL;
                                                   >> 885 
                                                   >> 886                 file->ignore_unreachables = true;
                                                   >> 887                 return rodata_rela;
                                                   >> 888         }
2140                                                  889 
                                                   >> 890         /* case 3 */
2141         /*                                       891         /*
2142          * Backward search using the @first_j    892          * Backward search using the @first_jump_src links, these help avoid
2143          * much of the 'in between' code. Whi    893          * much of the 'in between' code. Which avoids us getting confused by
2144          * it.                                   894          * it.
2145          */                                      895          */
2146         for (;                                !! 896         for (insn = list_prev_entry(insn, list);
2147              insn && insn_func(insn) && insn_ << 
2148              insn = insn->first_jump_src ?: p << 
2149                                                  897 
2150                 if (insn != orig_insn && insn !! 898              &insn->list != &file->insn_list &&
                                                   >> 899              insn->sec == func->sec &&
                                                   >> 900              insn->offset >= func->offset;
                                                   >> 901 
                                                   >> 902              insn = insn->first_jump_src ?: list_prev_entry(insn, list)) {
                                                   >> 903 
                                                   >> 904                 if (insn->type == INSN_JUMP_DYNAMIC)
2151                         break;                   905                         break;
2152                                                  906 
2153                 /* allow small jumps within t    907                 /* allow small jumps within the range */
2154                 if (insn->type == INSN_JUMP_U    908                 if (insn->type == INSN_JUMP_UNCONDITIONAL &&
2155                     insn->jump_dest &&           909                     insn->jump_dest &&
2156                     (insn->jump_dest->offset     910                     (insn->jump_dest->offset <= insn->offset ||
2157                      insn->jump_dest->offset     911                      insn->jump_dest->offset > orig_insn->offset))
2158                     break;                       912                     break;
2159                                                  913 
2160                 table_reloc = arch_find_switc !! 914                 /* look for a relocation which references .rodata */
2161                 if (!table_reloc)             !! 915                 text_rela = find_rela_by_dest_range(insn->sec, insn->offset,
                                                   >> 916                                                     insn->len);
                                                   >> 917                 if (!text_rela || text_rela->sym != file->rodata->sym)
2162                         continue;                918                         continue;
2163                 dest_insn = find_insn(file, t !! 919 
2164                 if (!dest_insn || !insn_func( !! 920                 /*
                                                   >> 921                  * Make sure the .rodata address isn't associated with a
                                                   >> 922                  * symbol.  gcc jump tables are anonymous data.
                                                   >> 923                  */
                                                   >> 924                 if (find_symbol_containing(file->rodata, text_rela->addend))
2165                         continue;                925                         continue;
2166                                                  926 
2167                 return table_reloc;           !! 927                 rodata_rela = find_rela_by_dest(file->rodata, text_rela->addend);
                                                   >> 928                 if (!rodata_rela)
                                                   >> 929                         continue;
                                                   >> 930 
                                                   >> 931                 return rodata_rela;
2168         }                                        932         }
2169                                                  933 
2170         return NULL;                             934         return NULL;
2171 }                                                935 }
2172                                                  936 
2173 /*                                            !! 937 
2174  * First pass: Mark the head of each jump tab !! 938 static int add_func_switch_tables(struct objtool_file *file,
2175  * we know when a given jump table ends and t !! 939                                   struct symbol *func)
2176  */                                           << 
2177 static void mark_func_jump_tables(struct objt << 
2178                                     struct sy << 
2179 {                                                940 {
2180         struct instruction *insn, *last = NUL !! 941         struct instruction *insn, *last = NULL, *prev_jump = NULL;
2181         struct reloc *reloc;                  !! 942         struct rela *rela, *prev_rela = NULL;
                                                   >> 943         int ret;
2182                                                  944 
2183         func_for_each_insn(file, func, insn)     945         func_for_each_insn(file, func, insn) {
2184                 if (!last)                       946                 if (!last)
2185                         last = insn;             947                         last = insn;
2186                                                  948 
2187                 /*                               949                 /*
2188                  * Store back-pointers for un    950                  * Store back-pointers for unconditional forward jumps such
2189                  * that find_jump_table() can !! 951                  * that find_switch_table() can back-track using those and
2190                  * avoid some potentially con    952                  * avoid some potentially confusing code.
2191                  */                              953                  */
2192                 if (insn->type == INSN_JUMP_U    954                 if (insn->type == INSN_JUMP_UNCONDITIONAL && insn->jump_dest &&
2193                     insn->offset > last->offs    955                     insn->offset > last->offset &&
2194                     insn->jump_dest->offset >    956                     insn->jump_dest->offset > insn->offset &&
2195                     !insn->jump_dest->first_j    957                     !insn->jump_dest->first_jump_src) {
2196                                                  958 
2197                         insn->jump_dest->firs    959                         insn->jump_dest->first_jump_src = insn;
2198                         last = insn->jump_des    960                         last = insn->jump_dest;
2199                 }                                961                 }
2200                                                  962 
2201                 if (insn->type != INSN_JUMP_D    963                 if (insn->type != INSN_JUMP_DYNAMIC)
2202                         continue;                964                         continue;
2203                                                  965 
2204                 reloc = find_jump_table(file, !! 966                 rela = find_switch_table(file, func, insn);
2205                 if (reloc)                    !! 967                 if (!rela)
2206                         insn->_jump_table = r << 
2207         }                                     << 
2208 }                                             << 
2209                                               << 
2210 static int add_func_jump_tables(struct objtoo << 
2211                                   struct symb << 
2212 {                                             << 
2213         struct instruction *insn, *insn_t1 =  << 
2214         int ret = 0;                          << 
2215                                               << 
2216         func_for_each_insn(file, func, insn)  << 
2217                 if (!insn_jump_table(insn))   << 
2218                         continue;                968                         continue;
2219                                                  969 
2220                 if (!insn_t1) {               !! 970                 /*
2221                         insn_t1 = insn;       !! 971                  * We found a switch table, but we don't know yet how big it
2222                         continue;             !! 972                  * is.  Don't add it until we reach the end of the function or
                                                   >> 973                  * the beginning of another switch table in the same function.
                                                   >> 974                  */
                                                   >> 975                 if (prev_jump) {
                                                   >> 976                         ret = add_switch_table(file, func, prev_jump, prev_rela,
                                                   >> 977                                                rela);
                                                   >> 978                         if (ret)
                                                   >> 979                                 return ret;
2223                 }                                980                 }
2224                                                  981 
2225                 insn_t2 = insn;               !! 982                 prev_jump = insn;
                                                   >> 983                 prev_rela = rela;
                                                   >> 984         }
2226                                                  985 
2227                 ret = add_jump_table(file, in !! 986         if (prev_jump) {
                                                   >> 987                 ret = add_switch_table(file, func, prev_jump, prev_rela, NULL);
2228                 if (ret)                         988                 if (ret)
2229                         return ret;              989                         return ret;
2230                                               << 
2231                 insn_t1 = insn_t2;            << 
2232         }                                        990         }
2233                                                  991 
2234         if (insn_t1)                          !! 992         return 0;
2235                 ret = add_jump_table(file, in << 
2236                                               << 
2237         return ret;                           << 
2238 }                                                993 }
2239                                                  994 
2240 /*                                               995 /*
2241  * For some switch statements, gcc generates     996  * For some switch statements, gcc generates a jump table in the .rodata
2242  * section which contains a list of addresses    997  * section which contains a list of addresses within the function to jump to.
2243  * This finds these jump tables and adds them    998  * This finds these jump tables and adds them to the insn->alts lists.
2244  */                                              999  */
2245 static int add_jump_table_alts(struct objtool !! 1000 static int add_switch_table_alts(struct objtool_file *file)
2246 {                                                1001 {
                                                   >> 1002         struct section *sec;
2247         struct symbol *func;                     1003         struct symbol *func;
2248         int ret;                                 1004         int ret;
2249                                                  1005 
2250         if (!file->rodata)                    !! 1006         if (!file->rodata || !file->rodata->rela)
2251                 return 0;                        1007                 return 0;
2252                                                  1008 
2253         for_each_sym(file, func) {            !! 1009         for_each_sec(file, sec) {
2254                 if (func->type != STT_FUNC)   !! 1010                 list_for_each_entry(func, &sec->symbol_list, list) {
2255                         continue;             !! 1011                         if (func->type != STT_FUNC)
                                                   >> 1012                                 continue;
2256                                                  1013 
2257                 mark_func_jump_tables(file, f !! 1014                         ret = add_func_switch_tables(file, func);
2258                 ret = add_func_jump_tables(fi !! 1015                         if (ret)
2259                 if (ret)                      !! 1016                                 return ret;
2260                         return ret;           !! 1017                 }
2261         }                                        1018         }
2262                                                  1019 
2263         return 0;                                1020         return 0;
2264 }                                                1021 }
2265                                                  1022 
2266 static void set_func_state(struct cfi_state * << 
2267 {                                             << 
2268         state->cfa = initial_func_cfi.cfa;    << 
2269         memcpy(&state->regs, &initial_func_cf << 
2270                CFI_NUM_REGS * sizeof(struct c << 
2271         state->stack_size = initial_func_cfi. << 
2272         state->type = UNWIND_HINT_TYPE_CALL;  << 
2273 }                                             << 
2274                                               << 
2275 static int read_unwind_hints(struct objtool_f    1023 static int read_unwind_hints(struct objtool_file *file)
2276 {                                                1024 {
2277         struct cfi_state cfi = init_cfi;      !! 1025         struct section *sec, *relasec;
2278         struct section *sec;                  !! 1026         struct rela *rela;
2279         struct unwind_hint *hint;                1027         struct unwind_hint *hint;
2280         struct instruction *insn;                1028         struct instruction *insn;
2281         struct reloc *reloc;                  !! 1029         struct cfi_reg *cfa;
2282         unsigned long offset;                 << 
2283         int i;                                   1030         int i;
2284                                                  1031 
2285         sec = find_section_by_name(file->elf,    1032         sec = find_section_by_name(file->elf, ".discard.unwind_hints");
2286         if (!sec)                                1033         if (!sec)
2287                 return 0;                        1034                 return 0;
2288                                                  1035 
2289         if (!sec->rsec) {                     !! 1036         relasec = sec->rela;
                                                   >> 1037         if (!relasec) {
2290                 WARN("missing .rela.discard.u    1038                 WARN("missing .rela.discard.unwind_hints section");
2291                 return -1;                       1039                 return -1;
2292         }                                        1040         }
2293                                                  1041 
2294         if (sec->sh.sh_size % sizeof(struct u !! 1042         if (sec->len % sizeof(struct unwind_hint)) {
2295                 WARN("struct unwind_hint size    1043                 WARN("struct unwind_hint size mismatch");
2296                 return -1;                       1044                 return -1;
2297         }                                        1045         }
2298                                                  1046 
2299         file->hints = true;                      1047         file->hints = true;
2300                                                  1048 
2301         for (i = 0; i < sec->sh.sh_size / siz !! 1049         for (i = 0; i < sec->len / sizeof(struct unwind_hint); i++) {
2302                 hint = (struct unwind_hint *)    1050                 hint = (struct unwind_hint *)sec->data->d_buf + i;
2303                                                  1051 
2304                 reloc = find_reloc_by_dest(fi !! 1052                 rela = find_rela_by_dest(sec, i * sizeof(*hint));
2305                 if (!reloc) {                 !! 1053                 if (!rela) {
2306                         WARN("can't find relo !! 1054                         WARN("can't find rela for unwind_hints[%d]", i);
2307                         return -1;               1055                         return -1;
2308                 }                                1056                 }
2309                                                  1057 
2310                 if (reloc->sym->type == STT_S !! 1058                 insn = find_insn(file, rela->sym->sec, rela->addend);
2311                         offset = reloc_addend << 
2312                 } else if (reloc->sym->local_ << 
2313                         offset = reloc->sym-> << 
2314                 } else {                      << 
2315                         WARN("unexpected relo << 
2316                         return -1;            << 
2317                 }                             << 
2318                                               << 
2319                 insn = find_insn(file, reloc- << 
2320                 if (!insn) {                     1059                 if (!insn) {
2321                         WARN("can't find insn    1060                         WARN("can't find insn for unwind_hints[%d]", i);
2322                         return -1;               1061                         return -1;
2323                 }                                1062                 }
2324                                                  1063 
2325                 insn->hint = true;            !! 1064                 cfa = &insn->state.cfa;
2326                                               << 
2327                 if (hint->type == UNWIND_HINT << 
2328                         insn->cfi = &force_un << 
2329                         continue;             << 
2330                 }                             << 
2331                                                  1065 
2332                 if (hint->type == UNWIND_HINT    1066                 if (hint->type == UNWIND_HINT_TYPE_SAVE) {
2333                         insn->hint = false;   << 
2334                         insn->save = true;       1067                         insn->save = true;
2335                         continue;                1068                         continue;
2336                 }                             << 
2337                                                  1069 
2338                 if (hint->type == UNWIND_HINT !! 1070                 } else if (hint->type == UNWIND_HINT_TYPE_RESTORE) {
2339                         insn->restore = true;    1071                         insn->restore = true;
                                                   >> 1072                         insn->hint = true;
2340                         continue;                1073                         continue;
2341                 }                                1074                 }
2342                                                  1075 
2343                 if (hint->type == UNWIND_HINT !! 1076                 insn->hint = true;
2344                         struct symbol *sym =  << 
2345                                               << 
2346                         if (sym && sym->bind  << 
2347                                 if (opts.ibt  << 
2348                                         WARN_ << 
2349                                 }             << 
2350                         }                     << 
2351                 }                             << 
2352                                               << 
2353                 if (hint->type == UNWIND_HINT << 
2354                         insn->cfi = &func_cfi << 
2355                         continue;             << 
2356                 }                             << 
2357                                               << 
2358                 if (insn->cfi)                << 
2359                         cfi = *(insn->cfi);   << 
2360                                               << 
2361                 if (arch_decode_hint_reg(hint << 
2362                         WARN_INSN(insn, "unsu << 
2363                         return -1;            << 
2364                 }                             << 
2365                                               << 
2366                 cfi.cfa.offset = bswap_if_nee << 
2367                 cfi.type = hint->type;        << 
2368                 cfi.signal = hint->signal;    << 
2369                                               << 
2370                 insn->cfi = cfi_hash_find_or_ << 
2371         }                                     << 
2372                                               << 
2373         return 0;                             << 
2374 }                                             << 
2375                                               << 
2376 static int read_noendbr_hints(struct objtool_ << 
2377 {                                             << 
2378         struct instruction *insn;             << 
2379         struct section *rsec;                 << 
2380         struct reloc *reloc;                  << 
2381                                               << 
2382         rsec = find_section_by_name(file->elf << 
2383         if (!rsec)                            << 
2384                 return 0;                     << 
2385                                                  1077 
2386         for_each_reloc(rsec, reloc) {         !! 1078                 switch (hint->sp_reg) {
2387                 insn = find_insn(file, reloc- !! 1079                 case ORC_REG_UNDEFINED:
2388                                  reloc->sym-> !! 1080                         cfa->base = CFI_UNDEFINED;
2389                 if (!insn) {                  !! 1081                         break;
2390                         WARN("bad .discard.no !! 1082                 case ORC_REG_SP:
                                                   >> 1083                         cfa->base = CFI_SP;
                                                   >> 1084                         break;
                                                   >> 1085                 case ORC_REG_BP:
                                                   >> 1086                         cfa->base = CFI_BP;
                                                   >> 1087                         break;
                                                   >> 1088                 case ORC_REG_SP_INDIRECT:
                                                   >> 1089                         cfa->base = CFI_SP_INDIRECT;
                                                   >> 1090                         break;
                                                   >> 1091                 case ORC_REG_R10:
                                                   >> 1092                         cfa->base = CFI_R10;
                                                   >> 1093                         break;
                                                   >> 1094                 case ORC_REG_R13:
                                                   >> 1095                         cfa->base = CFI_R13;
                                                   >> 1096                         break;
                                                   >> 1097                 case ORC_REG_DI:
                                                   >> 1098                         cfa->base = CFI_DI;
                                                   >> 1099                         break;
                                                   >> 1100                 case ORC_REG_DX:
                                                   >> 1101                         cfa->base = CFI_DX;
                                                   >> 1102                         break;
                                                   >> 1103                 default:
                                                   >> 1104                         WARN_FUNC("unsupported unwind_hint sp base reg %d",
                                                   >> 1105                                   insn->sec, insn->offset, hint->sp_reg);
2391                         return -1;               1106                         return -1;
2392                 }                                1107                 }
2393                                                  1108 
2394                 insn->noendbr = 1;            !! 1109                 cfa->offset = hint->sp_offset;
                                                   >> 1110                 insn->state.type = hint->type;
2395         }                                        1111         }
2396                                                  1112 
2397         return 0;                                1113         return 0;
2398 }                                                1114 }
2399                                                  1115 
2400 static int read_retpoline_hints(struct objtoo    1116 static int read_retpoline_hints(struct objtool_file *file)
2401 {                                                1117 {
2402         struct section *rsec;                 !! 1118         struct section *sec;
2403         struct instruction *insn;                1119         struct instruction *insn;
2404         struct reloc *reloc;                  !! 1120         struct rela *rela;
2405                                                  1121 
2406         rsec = find_section_by_name(file->elf !! 1122         sec = find_section_by_name(file->elf, ".rela.discard.retpoline_safe");
2407         if (!rsec)                            !! 1123         if (!sec)
2408                 return 0;                        1124                 return 0;
2409                                                  1125 
2410         for_each_reloc(rsec, reloc) {         !! 1126         list_for_each_entry(rela, &sec->rela_list, list) {
2411                 if (reloc->sym->type != STT_S !! 1127                 if (rela->sym->type != STT_SECTION) {
2412                         WARN("unexpected relo !! 1128                         WARN("unexpected relocation symbol type in %s", sec->name);
2413                         return -1;               1129                         return -1;
2414                 }                                1130                 }
2415                                                  1131 
2416                 insn = find_insn(file, reloc- !! 1132                 insn = find_insn(file, rela->sym->sec, rela->addend);
2417                 if (!insn) {                     1133                 if (!insn) {
2418                         WARN("bad .discard.re    1134                         WARN("bad .discard.retpoline_safe entry");
2419                         return -1;               1135                         return -1;
2420                 }                                1136                 }
2421                                                  1137 
2422                 if (insn->type != INSN_JUMP_D    1138                 if (insn->type != INSN_JUMP_DYNAMIC &&
2423                     insn->type != INSN_CALL_D !! 1139                     insn->type != INSN_CALL_DYNAMIC) {
2424                     insn->type != INSN_RETURN !! 1140                         WARN_FUNC("retpoline_safe hint not an indirect jump/call",
2425                     insn->type != INSN_NOP) { !! 1141                                   insn->sec, insn->offset);
2426                         WARN_INSN(insn, "retp << 
2427                         return -1;               1142                         return -1;
2428                 }                                1143                 }
2429                                                  1144 
2430                 insn->retpoline_safe = true;     1145                 insn->retpoline_safe = true;
2431         }                                        1146         }
2432                                                  1147 
2433         return 0;                                1148         return 0;
2434 }                                                1149 }
2435                                                  1150 
2436 static int read_instr_hints(struct objtool_fi << 
2437 {                                             << 
2438         struct section *rsec;                 << 
2439         struct instruction *insn;             << 
2440         struct reloc *reloc;                  << 
2441                                               << 
2442         rsec = find_section_by_name(file->elf << 
2443         if (!rsec)                            << 
2444                 return 0;                     << 
2445                                               << 
2446         for_each_reloc(rsec, reloc) {         << 
2447                 if (reloc->sym->type != STT_S << 
2448                         WARN("unexpected relo << 
2449                         return -1;            << 
2450                 }                             << 
2451                                               << 
2452                 insn = find_insn(file, reloc- << 
2453                 if (!insn) {                  << 
2454                         WARN("bad .discard.in << 
2455                         return -1;            << 
2456                 }                             << 
2457                                               << 
2458                 insn->instr--;                << 
2459         }                                     << 
2460                                               << 
2461         rsec = find_section_by_name(file->elf << 
2462         if (!rsec)                            << 
2463                 return 0;                     << 
2464                                               << 
2465         for_each_reloc(rsec, reloc) {         << 
2466                 if (reloc->sym->type != STT_S << 
2467                         WARN("unexpected relo << 
2468                         return -1;            << 
2469                 }                             << 
2470                                               << 
2471                 insn = find_insn(file, reloc- << 
2472                 if (!insn) {                  << 
2473                         WARN("bad .discard.in << 
2474                         return -1;            << 
2475                 }                             << 
2476                                               << 
2477                 insn->instr++;                << 
2478         }                                     << 
2479                                               << 
2480         return 0;                             << 
2481 }                                             << 
2482                                               << 
2483 static int read_validate_unret_hints(struct o << 
2484 {                                             << 
2485         struct section *rsec;                 << 
2486         struct instruction *insn;             << 
2487         struct reloc *reloc;                  << 
2488                                               << 
2489         rsec = find_section_by_name(file->elf << 
2490         if (!rsec)                            << 
2491                 return 0;                     << 
2492                                               << 
2493         for_each_reloc(rsec, reloc) {         << 
2494                 if (reloc->sym->type != STT_S << 
2495                         WARN("unexpected relo << 
2496                         return -1;            << 
2497                 }                             << 
2498                                               << 
2499                 insn = find_insn(file, reloc- << 
2500                 if (!insn) {                  << 
2501                         WARN("bad .discard.in << 
2502                         return -1;            << 
2503                 }                             << 
2504                 insn->unret = 1;              << 
2505         }                                     << 
2506                                               << 
2507         return 0;                             << 
2508 }                                             << 
2509                                               << 
2510                                               << 
2511 static int read_intra_function_calls(struct o << 
2512 {                                             << 
2513         struct instruction *insn;             << 
2514         struct section *rsec;                 << 
2515         struct reloc *reloc;                  << 
2516                                               << 
2517         rsec = find_section_by_name(file->elf << 
2518         if (!rsec)                            << 
2519                 return 0;                     << 
2520                                               << 
2521         for_each_reloc(rsec, reloc) {         << 
2522                 unsigned long dest_off;       << 
2523                                               << 
2524                 if (reloc->sym->type != STT_S << 
2525                         WARN("unexpected relo << 
2526                              rsec->name);     << 
2527                         return -1;            << 
2528                 }                             << 
2529                                               << 
2530                 insn = find_insn(file, reloc- << 
2531                 if (!insn) {                  << 
2532                         WARN("bad .discard.in << 
2533                         return -1;            << 
2534                 }                             << 
2535                                               << 
2536                 if (insn->type != INSN_CALL)  << 
2537                         WARN_INSN(insn, "intr << 
2538                         return -1;            << 
2539                 }                             << 
2540                                               << 
2541                 /*                            << 
2542                  * Treat intra-function CALLs << 
2543                  * See add_call_destinations( << 
2544                  * normal CALLs.              << 
2545                  */                           << 
2546                 insn->type = INSN_JUMP_UNCOND << 
2547                                               << 
2548                 dest_off = arch_jump_destinat << 
2549                 insn->jump_dest = find_insn(f << 
2550                 if (!insn->jump_dest) {       << 
2551                         WARN_INSN(insn, "can' << 
2552                                   insn->sec-> << 
2553                         return -1;            << 
2554                 }                             << 
2555         }                                     << 
2556                                               << 
2557         return 0;                             << 
2558 }                                             << 
2559                                               << 
2560 /*                                            << 
2561  * Return true if name matches an instrumenta << 
2562  * function from noinstr code can safely be r << 
2563  */                                           << 
2564 static bool is_profiling_func(const char *nam << 
2565 {                                             << 
2566         /*                                    << 
2567          * Many compilers cannot disable KCOV << 
2568          */                                   << 
2569         if (!strncmp(name, "__sanitizer_cov_" << 
2570                 return true;                  << 
2571                                               << 
2572         /*                                    << 
2573          * Some compilers currently do not re << 
2574          * __tsan_atomic_signal_fence (used f << 
2575          * the __no_sanitize_thread attribute << 
2576          * minimum Clang version is 14.0, thi << 
2577          */                                   << 
2578         if (!strncmp(name, "__tsan_func_", 12 << 
2579             !strcmp(name, "__tsan_atomic_sign << 
2580                 return true;                  << 
2581                                               << 
2582         return false;                         << 
2583 }                                             << 
2584                                               << 
2585 static int classify_symbols(struct objtool_fi << 
2586 {                                             << 
2587         struct symbol *func;                  << 
2588                                               << 
2589         for_each_sym(file, func) {            << 
2590                 if (func->type == STT_NOTYPE  << 
2591                         func->local_label = t << 
2592                                               << 
2593                 if (func->bind != STB_GLOBAL) << 
2594                         continue;             << 
2595                                               << 
2596                 if (!strncmp(func->name, STAT << 
2597                              strlen(STATIC_CA << 
2598                         func->static_call_tra << 
2599                                               << 
2600                 if (arch_is_retpoline(func))  << 
2601                         func->retpoline_thunk << 
2602                                               << 
2603                 if (arch_is_rethunk(func))    << 
2604                         func->return_thunk =  << 
2605                                               << 
2606                 if (arch_is_embedded_insn(fun << 
2607                         func->embedded_insn = << 
2608                                               << 
2609                 if (arch_ftrace_match(func->n << 
2610                         func->fentry = true;  << 
2611                                               << 
2612                 if (is_profiling_func(func->n << 
2613                         func->profiling_func  << 
2614         }                                     << 
2615                                               << 
2616         return 0;                             << 
2617 }                                             << 
2618                                               << 
2619 static void mark_rodata(struct objtool_file * << 
2620 {                                             << 
2621         struct section *sec;                  << 
2622         bool found = false;                   << 
2623                                               << 
2624         /*                                    << 
2625          * Search for the following rodata se << 
2626          * potentially contain jump tables:   << 
2627          *                                    << 
2628          * - .rodata: can contain GCC switch  << 
2629          * - .rodata.<func>: same, if -fdata- << 
2630          * - .rodata..c_jump_table: contains  << 
2631          *                                    << 
2632          * .rodata.str1.* sections are ignore << 
2633          */                                   << 
2634         for_each_sec(file, sec) {             << 
2635                 if (!strncmp(sec->name, ".rod << 
2636                     !strstr(sec->name, ".str1 << 
2637                         sec->rodata = true;   << 
2638                         found = true;         << 
2639                 }                             << 
2640         }                                     << 
2641                                               << 
2642         file->rodata = found;                 << 
2643 }                                             << 
2644                                               << 
2645 static int decode_sections(struct objtool_fil    1151 static int decode_sections(struct objtool_file *file)
2646 {                                                1152 {
2647         int ret;                                 1153         int ret;
2648                                                  1154 
2649         mark_rodata(file);                    !! 1155         ret = decode_instructions(file);
2650                                               << 
2651         ret = init_pv_ops(file);              << 
2652         if (ret)                              << 
2653                 return ret;                   << 
2654                                               << 
2655         /*                                    << 
2656          * Must be before add_{jump_call}_des << 
2657          */                                   << 
2658         ret = classify_symbols(file);         << 
2659         if (ret)                                 1156         if (ret)
2660                 return ret;                      1157                 return ret;
2661                                                  1158 
2662         ret = decode_instructions(file);      !! 1159         ret = add_dead_ends(file);
2663         if (ret)                                 1160         if (ret)
2664                 return ret;                      1161                 return ret;
2665                                                  1162 
2666         add_ignores(file);                       1163         add_ignores(file);
2667         add_uaccess_safe(file);               << 
2668                                               << 
2669         ret = add_ignore_alternatives(file);  << 
2670         if (ret)                              << 
2671                 return ret;                   << 
2672                                                  1164 
2673         /*                                    !! 1165         ret = add_nospec_ignores(file);
2674          * Must be before read_unwind_hints() << 
2675          */                                   << 
2676         ret = read_noendbr_hints(file);       << 
2677         if (ret)                                 1166         if (ret)
2678                 return ret;                      1167                 return ret;
2679                                                  1168 
2680         /*                                    << 
2681          * Must be before add_jump_destinatio << 
2682          * being set for alternatives, to ena << 
2683          */                                   << 
2684         if (opts.stackval || opts.orc || opts << 
2685                 ret = add_special_section_alt << 
2686                 if (ret)                      << 
2687                         return ret;           << 
2688         }                                     << 
2689                                               << 
2690         ret = add_jump_destinations(file);       1169         ret = add_jump_destinations(file);
2691         if (ret)                                 1170         if (ret)
2692                 return ret;                      1171                 return ret;
2693                                                  1172 
2694         /*                                    !! 1173         ret = add_special_section_alts(file);
2695          * Must be before add_call_destinatio << 
2696          * INSN_JUMP.                         << 
2697          */                                   << 
2698         ret = read_intra_function_calls(file) << 
2699         if (ret)                                 1174         if (ret)
2700                 return ret;                      1175                 return ret;
2701                                                  1176 
2702         ret = add_call_destinations(file);       1177         ret = add_call_destinations(file);
2703         if (ret)                                 1178         if (ret)
2704                 return ret;                      1179                 return ret;
2705                                                  1180 
2706         /*                                    !! 1181         ret = add_switch_table_alts(file);
2707          * Must be after add_call_destination << 
2708          * dead_end_function() marks.         << 
2709          */                                   << 
2710         ret = add_dead_ends(file);            << 
2711         if (ret)                              << 
2712                 return ret;                   << 
2713                                               << 
2714         ret = add_jump_table_alts(file);      << 
2715         if (ret)                                 1182         if (ret)
2716                 return ret;                      1183                 return ret;
2717                                                  1184 
2718         ret = read_unwind_hints(file);           1185         ret = read_unwind_hints(file);
2719         if (ret)                                 1186         if (ret)
2720                 return ret;                      1187                 return ret;
2721                                                  1188 
2722         ret = read_retpoline_hints(file);        1189         ret = read_retpoline_hints(file);
2723         if (ret)                                 1190         if (ret)
2724                 return ret;                      1191                 return ret;
2725                                                  1192 
2726         ret = read_instr_hints(file);         << 
2727         if (ret)                              << 
2728                 return ret;                   << 
2729                                               << 
2730         ret = read_validate_unret_hints(file) << 
2731         if (ret)                              << 
2732                 return ret;                   << 
2733                                               << 
2734         return 0;                                1193         return 0;
2735 }                                                1194 }
2736                                                  1195 
2737 static bool is_special_call(struct instructio !! 1196 static bool is_fentry_call(struct instruction *insn)
2738 {                                                1197 {
2739         if (insn->type == INSN_CALL) {        !! 1198         if (insn->type == INSN_CALL &&
2740                 struct symbol *dest = insn_ca !! 1199             insn->call_dest->type == STT_NOTYPE &&
2741                                               !! 1200             !strcmp(insn->call_dest->name, "__fentry__"))
2742                 if (!dest)                    !! 1201                 return true;
2743                         return false;         << 
2744                                               << 
2745                 if (dest->fentry || dest->emb << 
2746                         return true;          << 
2747         }                                     << 
2748                                                  1202 
2749         return false;                            1203         return false;
2750 }                                                1204 }
2751                                                  1205 
2752 static bool has_modified_stack_frame(struct i !! 1206 static bool has_modified_stack_frame(struct insn_state *state)
2753 {                                                1207 {
2754         struct cfi_state *cfi = &state->cfi;  << 
2755         int i;                                   1208         int i;
2756                                                  1209 
2757         if (cfi->cfa.base != initial_func_cfi !! 1210         if (state->cfa.base != initial_func_cfi.cfa.base ||
2758                 return true;                  !! 1211             state->cfa.offset != initial_func_cfi.cfa.offset ||
2759                                               !! 1212             state->stack_size != initial_func_cfi.cfa.offset ||
2760         if (cfi->cfa.offset != initial_func_c !! 1213             state->drap)
2761                 return true;                     1214                 return true;
2762                                                  1215 
2763         if (cfi->stack_size != initial_func_c !! 1216         for (i = 0; i < CFI_NUM_REGS; i++)
2764                 return true;                  !! 1217                 if (state->regs[i].base != initial_func_cfi.regs[i].base ||
2765                                               !! 1218                     state->regs[i].offset != initial_func_cfi.regs[i].offset)
2766         for (i = 0; i < CFI_NUM_REGS; i++) {  << 
2767                 if (cfi->regs[i].base != init << 
2768                     cfi->regs[i].offset != in << 
2769                         return true;             1219                         return true;
2770         }                                     << 
2771                                                  1220 
2772         return false;                            1221         return false;
2773 }                                                1222 }
2774                                                  1223 
2775 static bool check_reg_frame_pos(const struct  << 
2776                                 int expected_ << 
2777 {                                             << 
2778         return reg->base == CFI_CFA &&        << 
2779                reg->offset == expected_offset << 
2780 }                                             << 
2781                                               << 
2782 static bool has_valid_stack_frame(struct insn    1224 static bool has_valid_stack_frame(struct insn_state *state)
2783 {                                                1225 {
2784         struct cfi_state *cfi = &state->cfi;  !! 1226         if (state->cfa.base == CFI_BP && state->regs[CFI_BP].base == CFI_CFA &&
2785                                               !! 1227             state->regs[CFI_BP].offset == -16)
2786         if (cfi->cfa.base == CFI_BP &&        << 
2787             check_reg_frame_pos(&cfi->regs[CF << 
2788             check_reg_frame_pos(&cfi->regs[CF << 
2789                 return true;                     1228                 return true;
2790                                                  1229 
2791         if (cfi->drap && cfi->regs[CFI_BP].ba !! 1230         if (state->drap && state->regs[CFI_BP].base == CFI_BP)
2792                 return true;                     1231                 return true;
2793                                                  1232 
2794         return false;                            1233         return false;
2795 }                                                1234 }
2796                                                  1235 
2797 static int update_cfi_state_regs(struct instr !! 1236 static int update_insn_state_regs(struct instruction *insn, struct insn_state *state)
2798                                   struct cfi_ << 
2799                                   struct stac << 
2800 {                                                1237 {
2801         struct cfi_reg *cfa = &cfi->cfa;      !! 1238         struct cfi_reg *cfa = &state->cfa;
                                                   >> 1239         struct stack_op *op = &insn->stack_op;
2802                                                  1240 
2803         if (cfa->base != CFI_SP && cfa->base  !! 1241         if (cfa->base != CFI_SP)
2804                 return 0;                        1242                 return 0;
2805                                                  1243 
2806         /* push */                               1244         /* push */
2807         if (op->dest.type == OP_DEST_PUSH ||  !! 1245         if (op->dest.type == OP_DEST_PUSH)
2808                 cfa->offset += 8;                1246                 cfa->offset += 8;
2809                                                  1247 
2810         /* pop */                                1248         /* pop */
2811         if (op->src.type == OP_SRC_POP || op- !! 1249         if (op->src.type == OP_SRC_POP)
2812                 cfa->offset -= 8;                1250                 cfa->offset -= 8;
2813                                                  1251 
2814         /* add immediate to sp */                1252         /* add immediate to sp */
2815         if (op->dest.type == OP_DEST_REG && o    1253         if (op->dest.type == OP_DEST_REG && op->src.type == OP_SRC_ADD &&
2816             op->dest.reg == CFI_SP && op->src    1254             op->dest.reg == CFI_SP && op->src.reg == CFI_SP)
2817                 cfa->offset -= op->src.offset    1255                 cfa->offset -= op->src.offset;
2818                                                  1256 
2819         return 0;                                1257         return 0;
2820 }                                                1258 }
2821                                                  1259 
2822 static void save_reg(struct cfi_state *cfi, u !! 1260 static void save_reg(struct insn_state *state, unsigned char reg, int base,
                                                   >> 1261                      int offset)
2823 {                                                1262 {
2824         if (arch_callee_saved_reg(reg) &&        1263         if (arch_callee_saved_reg(reg) &&
2825             cfi->regs[reg].base == CFI_UNDEFI !! 1264             state->regs[reg].base == CFI_UNDEFINED) {
2826                 cfi->regs[reg].base = base;   !! 1265                 state->regs[reg].base = base;
2827                 cfi->regs[reg].offset = offse !! 1266                 state->regs[reg].offset = offset;
2828         }                                        1267         }
2829 }                                                1268 }
2830                                                  1269 
2831 static void restore_reg(struct cfi_state *cfi !! 1270 static void restore_reg(struct insn_state *state, unsigned char reg)
2832 {                                                1271 {
2833         cfi->regs[reg].base = initial_func_cf !! 1272         state->regs[reg].base = CFI_UNDEFINED;
2834         cfi->regs[reg].offset = initial_func_ !! 1273         state->regs[reg].offset = 0;
2835 }                                                1274 }
2836                                                  1275 
2837 /*                                               1276 /*
2838  * A note about DRAP stack alignment:            1277  * A note about DRAP stack alignment:
2839  *                                               1278  *
2840  * GCC has the concept of a DRAP register, wh    1279  * GCC has the concept of a DRAP register, which is used to help keep track of
2841  * the stack pointer when aligning the stack.    1280  * the stack pointer when aligning the stack.  r10 or r13 is used as the DRAP
2842  * register.  The typical DRAP pattern is:       1281  * register.  The typical DRAP pattern is:
2843  *                                               1282  *
2844  *   4c 8d 54 24 08             lea    0x8(%r    1283  *   4c 8d 54 24 08             lea    0x8(%rsp),%r10
2845  *   48 83 e4 c0                and    $0xfff    1284  *   48 83 e4 c0                and    $0xffffffffffffffc0,%rsp
2846  *   41 ff 72 f8                pushq  -0x8(%    1285  *   41 ff 72 f8                pushq  -0x8(%r10)
2847  *   55                         push   %rbp      1286  *   55                         push   %rbp
2848  *   48 89 e5                   mov    %rsp,%    1287  *   48 89 e5                   mov    %rsp,%rbp
2849  *                              (more pushes)    1288  *                              (more pushes)
2850  *   41 52                      push   %r10      1289  *   41 52                      push   %r10
2851  *                              ...              1290  *                              ...
2852  *   41 5a                      pop    %r10      1291  *   41 5a                      pop    %r10
2853  *                              (more pops)      1292  *                              (more pops)
2854  *   5d                         pop    %rbp      1293  *   5d                         pop    %rbp
2855  *   49 8d 62 f8                lea    -0x8(%    1294  *   49 8d 62 f8                lea    -0x8(%r10),%rsp
2856  *   c3                         retq             1295  *   c3                         retq
2857  *                                               1296  *
2858  * There are some variations in the epilogues    1297  * There are some variations in the epilogues, like:
2859  *                                               1298  *
2860  *   5b                         pop    %rbx      1299  *   5b                         pop    %rbx
2861  *   41 5a                      pop    %r10      1300  *   41 5a                      pop    %r10
2862  *   41 5c                      pop    %r12      1301  *   41 5c                      pop    %r12
2863  *   41 5d                      pop    %r13      1302  *   41 5d                      pop    %r13
2864  *   41 5e                      pop    %r14      1303  *   41 5e                      pop    %r14
2865  *   c9                         leaveq           1304  *   c9                         leaveq
2866  *   49 8d 62 f8                lea    -0x8(%    1305  *   49 8d 62 f8                lea    -0x8(%r10),%rsp
2867  *   c3                         retq             1306  *   c3                         retq
2868  *                                               1307  *
2869  * and:                                          1308  * and:
2870  *                                               1309  *
2871  *   4c 8b 55 e8                mov    -0x18(    1310  *   4c 8b 55 e8                mov    -0x18(%rbp),%r10
2872  *   48 8b 5d e0                mov    -0x20(    1311  *   48 8b 5d e0                mov    -0x20(%rbp),%rbx
2873  *   4c 8b 65 f0                mov    -0x10(    1312  *   4c 8b 65 f0                mov    -0x10(%rbp),%r12
2874  *   4c 8b 6d f8                mov    -0x8(%    1313  *   4c 8b 6d f8                mov    -0x8(%rbp),%r13
2875  *   c9                         leaveq           1314  *   c9                         leaveq
2876  *   49 8d 62 f8                lea    -0x8(%    1315  *   49 8d 62 f8                lea    -0x8(%r10),%rsp
2877  *   c3                         retq             1316  *   c3                         retq
2878  *                                               1317  *
2879  * Sometimes r13 is used as the DRAP register    1318  * Sometimes r13 is used as the DRAP register, in which case it's saved and
2880  * restored beforehand:                          1319  * restored beforehand:
2881  *                                               1320  *
2882  *   41 55                      push   %r13      1321  *   41 55                      push   %r13
2883  *   4c 8d 6c 24 10             lea    0x10(%    1322  *   4c 8d 6c 24 10             lea    0x10(%rsp),%r13
2884  *   48 83 e4 f0                and    $0xfff    1323  *   48 83 e4 f0                and    $0xfffffffffffffff0,%rsp
2885  *                              ...              1324  *                              ...
2886  *   49 8d 65 f0                lea    -0x10(    1325  *   49 8d 65 f0                lea    -0x10(%r13),%rsp
2887  *   41 5d                      pop    %r13      1326  *   41 5d                      pop    %r13
2888  *   c3                         retq             1327  *   c3                         retq
2889  */                                              1328  */
2890 static int update_cfi_state(struct instructio !! 1329 static int update_insn_state(struct instruction *insn, struct insn_state *state)
2891                             struct instructio << 
2892                             struct cfi_state  << 
2893 {                                                1330 {
2894         struct cfi_reg *cfa = &cfi->cfa;      !! 1331         struct stack_op *op = &insn->stack_op;
2895         struct cfi_reg *regs = cfi->regs;     !! 1332         struct cfi_reg *cfa = &state->cfa;
2896                                               !! 1333         struct cfi_reg *regs = state->regs;
2897         /* ignore UNWIND_HINT_UNDEFINED regio << 
2898         if (cfi->force_undefined)             << 
2899                 return 0;                     << 
2900                                                  1334 
2901         /* stack operations don't make sense     1335         /* stack operations don't make sense with an undefined CFA */
2902         if (cfa->base == CFI_UNDEFINED) {        1336         if (cfa->base == CFI_UNDEFINED) {
2903                 if (insn_func(insn)) {        !! 1337                 if (insn->func) {
2904                         WARN_INSN(insn, "unde !! 1338                         WARN_FUNC("undefined stack state", insn->sec, insn->offset);
2905                         return -1;               1339                         return -1;
2906                 }                                1340                 }
2907                 return 0;                        1341                 return 0;
2908         }                                        1342         }
2909                                                  1343 
2910         if (cfi->type == UNWIND_HINT_TYPE_REG !! 1344         if (state->type == ORC_TYPE_REGS || state->type == ORC_TYPE_REGS_IRET)
2911             cfi->type == UNWIND_HINT_TYPE_REG !! 1345                 return update_insn_state_regs(insn, state);
2912                 return update_cfi_state_regs( << 
2913                                                  1346 
2914         switch (op->dest.type) {                 1347         switch (op->dest.type) {
2915                                                  1348 
2916         case OP_DEST_REG:                        1349         case OP_DEST_REG:
2917                 switch (op->src.type) {          1350                 switch (op->src.type) {
2918                                                  1351 
2919                 case OP_SRC_REG:                 1352                 case OP_SRC_REG:
2920                         if (op->src.reg == CF    1353                         if (op->src.reg == CFI_SP && op->dest.reg == CFI_BP &&
2921                             cfa->base == CFI_    1354                             cfa->base == CFI_SP &&
2922                             check_reg_frame_p !! 1355                             regs[CFI_BP].base == CFI_CFA &&
                                                   >> 1356                             regs[CFI_BP].offset == -cfa->offset) {
2923                                                  1357 
2924                                 /* mov %rsp,     1358                                 /* mov %rsp, %rbp */
2925                                 cfa->base = o    1359                                 cfa->base = op->dest.reg;
2926                                 cfi->bp_scrat !! 1360                                 state->bp_scratch = false;
2927                         }                        1361                         }
2928                                                  1362 
2929                         else if (op->src.reg     1363                         else if (op->src.reg == CFI_SP &&
2930                                  op->dest.reg !! 1364                                  op->dest.reg == CFI_BP && state->drap) {
2931                                                  1365 
2932                                 /* drap: mov     1366                                 /* drap: mov %rsp, %rbp */
2933                                 regs[CFI_BP].    1367                                 regs[CFI_BP].base = CFI_BP;
2934                                 regs[CFI_BP]. !! 1368                                 regs[CFI_BP].offset = -state->stack_size;
2935                                 cfi->bp_scrat !! 1369                                 state->bp_scratch = false;
2936                         }                        1370                         }
2937                                                  1371 
2938                         else if (op->src.reg     1372                         else if (op->src.reg == CFI_SP && cfa->base == CFI_SP) {
2939                                                  1373 
2940                                 /*               1374                                 /*
2941                                  * mov %rsp,     1375                                  * mov %rsp, %reg
2942                                  *               1376                                  *
2943                                  * This is ne    1377                                  * This is needed for the rare case where GCC
2944                                  * does:         1378                                  * does:
2945                                  *               1379                                  *
2946                                  *   mov    %    1380                                  *   mov    %rsp, %rax
2947                                  *   ...         1381                                  *   ...
2948                                  *   mov    %    1382                                  *   mov    %rax, %rsp
2949                                  */              1383                                  */
2950                                 cfi->vals[op- !! 1384                                 state->vals[op->dest.reg].base = CFI_CFA;
2951                                 cfi->vals[op- !! 1385                                 state->vals[op->dest.reg].offset = -state->stack_size;
2952                         }                     << 
2953                                               << 
2954                         else if (op->src.reg  << 
2955                                  (cfa->base = << 
2956                                               << 
2957                                 /*            << 
2958                                  * mov %rbp,  << 
2959                                  *            << 
2960                                  * Restore th << 
2961                                  */           << 
2962                                 cfi->stack_si << 
2963                         }                        1386                         }
2964                                                  1387 
2965                         else if (op->dest.reg    1388                         else if (op->dest.reg == cfa->base) {
2966                                                  1389 
2967                                 /* mov %reg,     1390                                 /* mov %reg, %rsp */
2968                                 if (cfa->base    1391                                 if (cfa->base == CFI_SP &&
2969                                     cfi->vals !! 1392                                     state->vals[op->src.reg].base == CFI_CFA) {
2970                                                  1393 
2971                                         /*       1394                                         /*
2972                                          * Th    1395                                          * This is needed for the rare case
2973                                          * wh    1396                                          * where GCC does something dumb like:
2974                                          *       1397                                          *
2975                                          *       1398                                          *   lea    0x8(%rsp), %rcx
2976                                          *       1399                                          *   ...
2977                                          *       1400                                          *   mov    %rcx, %rsp
2978                                          */      1401                                          */
2979                                         cfa-> !! 1402                                         cfa->offset = -state->vals[op->src.reg].offset;
2980                                         cfi-> !! 1403                                         state->stack_size = cfa->offset;
2981                                               << 
2982                                 } else if (cf << 
2983                                            cf << 
2984                                            cf << 
2985                                               << 
2986                                         /*    << 
2987                                          * St << 
2988                                          *    << 
2989                                          * 1: << 
2990                                          * 2: << 
2991                                          *    << 
2992                                          * 3: << 
2993                                          *    << 
2994                                          * Wh << 
2995                                          *    << 
2996                                          * 1  << 
2997                                          *    << 
2998                                          *    << 
2999                                          *    << 
3000                                          * 2  << 
3001                                          *    << 
3002                                          * 3  << 
3003                                          *    << 
3004                                          *    << 
3005                                          * No << 
3006                                          * he << 
3007                                          * wh << 
3008                                          * wi << 
3009                                          * of << 
3010                                          * (% << 
3011                                          */   << 
3012                                         cfa-> << 
3013                                                  1404 
3014                                 } else {         1405                                 } else {
3015                                         cfa->    1406                                         cfa->base = CFI_UNDEFINED;
3016                                         cfa->    1407                                         cfa->offset = 0;
3017                                 }                1408                                 }
3018                         }                        1409                         }
3019                                                  1410 
3020                         else if (op->dest.reg << 
3021                                  cfi->vals[op << 
3022                                  cfi->vals[op << 
3023                                               << 
3024                                 /*            << 
3025                                  * The same s << 
3026                                  * because we << 
3027                                  * will becom << 
3028                                  * PUSH so th << 
3029                                  */           << 
3030                                 cfi->stack_si << 
3031                         }                     << 
3032                                               << 
3033                                               << 
3034                         break;                   1411                         break;
3035                                                  1412 
3036                 case OP_SRC_ADD:                 1413                 case OP_SRC_ADD:
3037                         if (op->dest.reg == C    1414                         if (op->dest.reg == CFI_SP && op->src.reg == CFI_SP) {
3038                                                  1415 
3039                                 /* add imm, %    1416                                 /* add imm, %rsp */
3040                                 cfi->stack_si !! 1417                                 state->stack_size -= op->src.offset;
3041                                 if (cfa->base    1418                                 if (cfa->base == CFI_SP)
3042                                         cfa->    1419                                         cfa->offset -= op->src.offset;
3043                                 break;           1420                                 break;
3044                         }                        1421                         }
3045                                                  1422 
3046                         if (op->dest.reg == C << 
3047                             insn->sym->frame_ << 
3048                                 /* addi.d fp, << 
3049                                 if (cfa->base << 
3050                                         cfa-> << 
3051                                         cfa-> << 
3052                                 }             << 
3053                                 break;        << 
3054                         }                     << 
3055                                               << 
3056                         if (op->dest.reg == C    1423                         if (op->dest.reg == CFI_SP && op->src.reg == CFI_BP) {
3057                                 /* addi.d sp, !! 1424 
3058                                 if (cfa->base !! 1425                                 /* lea disp(%rbp), %rsp */
3059                                         if (i !! 1426                                 state->stack_size = -(op->src.offset + regs[CFI_BP].offset);
3060                                               << 
3061                                               << 
3062                                         }     << 
3063                                 } else {      << 
3064                                         /* le << 
3065                                         cfi-> << 
3066                                 }             << 
3067                                 break;           1427                                 break;
3068                         }                        1428                         }
3069                                                  1429 
3070                         if (op->src.reg == CF    1430                         if (op->src.reg == CFI_SP && cfa->base == CFI_SP) {
3071                                                  1431 
3072                                 /* drap: lea     1432                                 /* drap: lea disp(%rsp), %drap */
3073                                 cfi->drap_reg !! 1433                                 state->drap_reg = op->dest.reg;
3074                                                  1434 
3075                                 /*               1435                                 /*
3076                                  * lea disp(%    1436                                  * lea disp(%rsp), %reg
3077                                  *               1437                                  *
3078                                  * This is ne    1438                                  * This is needed for the rare case where GCC
3079                                  * does somet    1439                                  * does something dumb like:
3080                                  *               1440                                  *
3081                                  *   lea    0    1441                                  *   lea    0x8(%rsp), %rcx
3082                                  *   ...         1442                                  *   ...
3083                                  *   mov    %    1443                                  *   mov    %rcx, %rsp
3084                                  */              1444                                  */
3085                                 cfi->vals[op- !! 1445                                 state->vals[op->dest.reg].base = CFI_CFA;
3086                                 cfi->vals[op- !! 1446                                 state->vals[op->dest.reg].offset = \
3087                                         -cfi- !! 1447                                         -state->stack_size + op->src.offset;
3088                                                  1448 
3089                                 break;           1449                                 break;
3090                         }                        1450                         }
3091                                                  1451 
3092                         if (cfi->drap && op-> !! 1452                         if (state->drap && op->dest.reg == CFI_SP &&
3093                             op->src.reg == cf !! 1453                             op->src.reg == state->drap_reg) {
3094                                                  1454 
3095                                  /* drap: lea    1455                                  /* drap: lea disp(%drap), %rsp */
3096                                 cfa->base = C    1456                                 cfa->base = CFI_SP;
3097                                 cfa->offset = !! 1457                                 cfa->offset = state->stack_size = -op->src.offset;
3098                                 cfi->drap_reg !! 1458                                 state->drap_reg = CFI_UNDEFINED;
3099                                 cfi->drap = f !! 1459                                 state->drap = false;
3100                                 break;           1460                                 break;
3101                         }                        1461                         }
3102                                                  1462 
3103                         if (op->dest.reg == c !! 1463                         if (op->dest.reg == state->cfa.base) {
3104                                 WARN_INSN(ins !! 1464                                 WARN_FUNC("unsupported stack register modification",
                                                   >> 1465                                           insn->sec, insn->offset);
3105                                 return -1;       1466                                 return -1;
3106                         }                        1467                         }
3107                                                  1468 
3108                         break;                   1469                         break;
3109                                                  1470 
3110                 case OP_SRC_AND:                 1471                 case OP_SRC_AND:
3111                         if (op->dest.reg != C    1472                         if (op->dest.reg != CFI_SP ||
3112                             (cfi->drap_reg != !! 1473                             (state->drap_reg != CFI_UNDEFINED && cfa->base != CFI_SP) ||
3113                             (cfi->drap_reg == !! 1474                             (state->drap_reg == CFI_UNDEFINED && cfa->base != CFI_BP)) {
3114                                 WARN_INSN(ins !! 1475                                 WARN_FUNC("unsupported stack pointer realignment",
                                                   >> 1476                                           insn->sec, insn->offset);
3115                                 return -1;       1477                                 return -1;
3116                         }                        1478                         }
3117                                                  1479 
3118                         if (cfi->drap_reg !=  !! 1480                         if (state->drap_reg != CFI_UNDEFINED) {
3119                                 /* drap: and     1481                                 /* drap: and imm, %rsp */
3120                                 cfa->base = c !! 1482                                 cfa->base = state->drap_reg;
3121                                 cfa->offset = !! 1483                                 cfa->offset = state->stack_size = 0;
3122                                 cfi->drap = t !! 1484                                 state->drap = true;
3123                         }                        1485                         }
3124                                                  1486 
3125                         /*                       1487                         /*
3126                          * Older versions of     1488                          * Older versions of GCC (4.8ish) realign the stack
3127                          * without DRAP, with    1489                          * without DRAP, with a frame pointer.
3128                          */                      1490                          */
3129                                                  1491 
3130                         break;                   1492                         break;
3131                                                  1493 
3132                 case OP_SRC_POP:                 1494                 case OP_SRC_POP:
3133                 case OP_SRC_POPF:             !! 1495                         if (!state->drap && op->dest.type == OP_DEST_REG &&
3134                         if (op->dest.reg == C !! 1496                             op->dest.reg == cfa->base) {
3135                                               << 
3136                                 /* pop %rsp;  << 
3137                                 cfa->base = C << 
3138                                 break;        << 
3139                         }                     << 
3140                                               << 
3141                         if (!cfi->drap && op- << 
3142                                                  1497 
3143                                 /* pop %rbp *    1498                                 /* pop %rbp */
3144                                 cfa->base = C    1499                                 cfa->base = CFI_SP;
3145                         }                        1500                         }
3146                                                  1501 
3147                         if (cfi->drap && cfa- !! 1502                         if (state->drap && cfa->base == CFI_BP_INDIRECT &&
3148                             op->dest.reg == c !! 1503                             op->dest.type == OP_DEST_REG &&
3149                             cfi->drap_offset  !! 1504                             op->dest.reg == state->drap_reg &&
                                                   >> 1505                             state->drap_offset == -state->stack_size) {
3150                                                  1506 
3151                                 /* drap: pop     1507                                 /* drap: pop %drap */
3152                                 cfa->base = c !! 1508                                 cfa->base = state->drap_reg;
3153                                 cfa->offset =    1509                                 cfa->offset = 0;
3154                                 cfi->drap_off !! 1510                                 state->drap_offset = -1;
3155                                                  1511 
3156                         } else if (cfi->stack !! 1512                         } else if (regs[op->dest.reg].offset == -state->stack_size) {
3157                                                  1513 
3158                                 /* pop %reg *    1514                                 /* pop %reg */
3159                                 restore_reg(c !! 1515                                 restore_reg(state, op->dest.reg);
3160                         }                        1516                         }
3161                                                  1517 
3162                         cfi->stack_size -= 8; !! 1518                         state->stack_size -= 8;
3163                         if (cfa->base == CFI_    1519                         if (cfa->base == CFI_SP)
3164                                 cfa->offset -    1520                                 cfa->offset -= 8;
3165                                                  1521 
3166                         break;                   1522                         break;
3167                                                  1523 
3168                 case OP_SRC_REG_INDIRECT:        1524                 case OP_SRC_REG_INDIRECT:
3169                         if (!cfi->drap && op- !! 1525                         if (state->drap && op->src.reg == CFI_BP &&
3170                             op->dest.reg == C !! 1526                             op->src.offset == state->drap_offset) {
3171                                               << 
3172                                 /* mov disp(% << 
3173                                 cfa->base = C << 
3174                                 cfa->offset = << 
3175                         }                     << 
3176                                               << 
3177                         if (cfi->drap && op-> << 
3178                             op->src.offset == << 
3179                                                  1527 
3180                                 /* drap: mov     1528                                 /* drap: mov disp(%rbp), %drap */
3181                                 cfa->base = c !! 1529                                 cfa->base = state->drap_reg;
3182                                 cfa->offset =    1530                                 cfa->offset = 0;
3183                                 cfi->drap_off !! 1531                                 state->drap_offset = -1;
3184                         }                        1532                         }
3185                                                  1533 
3186                         if (cfi->drap && op-> !! 1534                         if (state->drap && op->src.reg == CFI_BP &&
3187                             op->src.offset ==    1535                             op->src.offset == regs[op->dest.reg].offset) {
3188                                                  1536 
3189                                 /* drap: mov     1537                                 /* drap: mov disp(%rbp), %reg */
3190                                 restore_reg(c !! 1538                                 restore_reg(state, op->dest.reg);
3191                                                  1539 
3192                         } else if (op->src.re    1540                         } else if (op->src.reg == cfa->base &&
3193                             op->src.offset ==    1541                             op->src.offset == regs[op->dest.reg].offset + cfa->offset) {
3194                                                  1542 
3195                                 /* mov disp(%    1543                                 /* mov disp(%rbp), %reg */
3196                                 /* mov disp(%    1544                                 /* mov disp(%rsp), %reg */
3197                                 restore_reg(c !! 1545                                 restore_reg(state, op->dest.reg);
3198                                               << 
3199                         } else if (op->src.re << 
3200                                    op->src.of << 
3201                                               << 
3202                                 /* mov disp(% << 
3203                                 restore_reg(c << 
3204                         }                        1546                         }
3205                                                  1547 
3206                         break;                   1548                         break;
3207                                                  1549 
3208                 default:                         1550                 default:
3209                         WARN_INSN(insn, "unkn !! 1551                         WARN_FUNC("unknown stack-related instruction",
                                                   >> 1552                                   insn->sec, insn->offset);
3210                         return -1;               1553                         return -1;
3211                 }                                1554                 }
3212                                                  1555 
3213                 break;                           1556                 break;
3214                                                  1557 
3215         case OP_DEST_PUSH:                       1558         case OP_DEST_PUSH:
3216         case OP_DEST_PUSHF:                   !! 1559                 state->stack_size += 8;
3217                 cfi->stack_size += 8;         << 
3218                 if (cfa->base == CFI_SP)         1560                 if (cfa->base == CFI_SP)
3219                         cfa->offset += 8;        1561                         cfa->offset += 8;
3220                                                  1562 
3221                 if (op->src.type != OP_SRC_RE    1563                 if (op->src.type != OP_SRC_REG)
3222                         break;                   1564                         break;
3223                                                  1565 
3224                 if (cfi->drap) {              !! 1566                 if (state->drap) {
3225                         if (op->src.reg == cf !! 1567                         if (op->src.reg == cfa->base && op->src.reg == state->drap_reg) {
3226                                                  1568 
3227                                 /* drap: push    1569                                 /* drap: push %drap */
3228                                 cfa->base = C    1570                                 cfa->base = CFI_BP_INDIRECT;
3229                                 cfa->offset = !! 1571                                 cfa->offset = -state->stack_size;
3230                                                  1572 
3231                                 /* save drap     1573                                 /* save drap so we know when to restore it */
3232                                 cfi->drap_off !! 1574                                 state->drap_offset = -state->stack_size;
3233                                                  1575 
3234                         } else if (op->src.re !! 1576                         } else if (op->src.reg == CFI_BP && cfa->base == state->drap_reg) {
3235                                                  1577 
3236                                 /* drap: push    1578                                 /* drap: push %rbp */
3237                                 cfi->stack_si !! 1579                                 state->stack_size = 0;
3238                                                  1580 
3239                         } else {              !! 1581                         } else if (regs[op->src.reg].base == CFI_UNDEFINED) {
3240                                                  1582 
3241                                 /* drap: push    1583                                 /* drap: push %reg */
3242                                 save_reg(cfi, !! 1584                                 save_reg(state, op->src.reg, CFI_BP, -state->stack_size);
3243                         }                        1585                         }
3244                                                  1586 
3245                 } else {                         1587                 } else {
3246                                                  1588 
3247                         /* push %reg */          1589                         /* push %reg */
3248                         save_reg(cfi, op->src !! 1590                         save_reg(state, op->src.reg, CFI_CFA, -state->stack_size);
3249                 }                                1591                 }
3250                                                  1592 
3251                 /* detect when asm code uses     1593                 /* detect when asm code uses rbp as a scratch register */
3252                 if (opts.stackval && insn_fun !! 1594                 if (!no_fp && insn->func && op->src.reg == CFI_BP &&
3253                     cfa->base != CFI_BP)         1595                     cfa->base != CFI_BP)
3254                         cfi->bp_scratch = tru !! 1596                         state->bp_scratch = true;
3255                 break;                           1597                 break;
3256                                                  1598 
3257         case OP_DEST_REG_INDIRECT:               1599         case OP_DEST_REG_INDIRECT:
3258                                                  1600 
3259                 if (cfi->drap) {              !! 1601                 if (state->drap) {
3260                         if (op->src.reg == cf !! 1602                         if (op->src.reg == cfa->base && op->src.reg == state->drap_reg) {
3261                                                  1603 
3262                                 /* drap: mov     1604                                 /* drap: mov %drap, disp(%rbp) */
3263                                 cfa->base = C    1605                                 cfa->base = CFI_BP_INDIRECT;
3264                                 cfa->offset =    1606                                 cfa->offset = op->dest.offset;
3265                                                  1607 
3266                                 /* save drap     1608                                 /* save drap offset so we know when to restore it */
3267                                 cfi->drap_off !! 1609                                 state->drap_offset = op->dest.offset;
3268                         } else {              !! 1610                         }
                                                   >> 1611 
                                                   >> 1612                         else if (regs[op->src.reg].base == CFI_UNDEFINED) {
3269                                                  1613 
3270                                 /* drap: mov     1614                                 /* drap: mov reg, disp(%rbp) */
3271                                 save_reg(cfi, !! 1615                                 save_reg(state, op->src.reg, CFI_BP, op->dest.offset);
3272                         }                        1616                         }
3273                                                  1617 
3274                 } else if (op->dest.reg == cf    1618                 } else if (op->dest.reg == cfa->base) {
3275                                                  1619 
3276                         /* mov reg, disp(%rbp    1620                         /* mov reg, disp(%rbp) */
3277                         /* mov reg, disp(%rsp    1621                         /* mov reg, disp(%rsp) */
3278                         save_reg(cfi, op->src !! 1622                         save_reg(state, op->src.reg, CFI_CFA,
3279                                  op->dest.off !! 1623                                  op->dest.offset - state->cfa.offset);
                                                   >> 1624                 }
3280                                                  1625 
3281                 } else if (op->dest.reg == CF !! 1626                 break;
3282                                                  1627 
3283                         /* mov reg, disp(%rsp !! 1628         case OP_DEST_LEAVE:
3284                         save_reg(cfi, op->src !! 1629                 if ((!state->drap && cfa->base != CFI_BP) ||
3285                                  op->dest.off !! 1630                     (state->drap && cfa->base != state->drap_reg)) {
                                                   >> 1631                         WARN_FUNC("leave instruction with modified stack frame",
                                                   >> 1632                                   insn->sec, insn->offset);
                                                   >> 1633                         return -1;
                                                   >> 1634                 }
                                                   >> 1635 
                                                   >> 1636                 /* leave (mov %rbp, %rsp; pop %rbp) */
3286                                                  1637 
3287                 } else if (op->src.reg == CFI !! 1638                 state->stack_size = -state->regs[CFI_BP].offset - 8;
                                                   >> 1639                 restore_reg(state, CFI_BP);
3288                                                  1640 
3289                         /* mov %rsp, (%reg);  !! 1641                 if (!state->drap) {
3290                         cfi->vals[op->dest.re !! 1642                         cfa->base = CFI_SP;
3291                         cfi->vals[op->dest.re !! 1643                         cfa->offset -= 8;
3292                 }                                1644                 }
3293                                                  1645 
3294                 break;                           1646                 break;
3295                                                  1647 
3296         case OP_DEST_MEM:                        1648         case OP_DEST_MEM:
3297                 if (op->src.type != OP_SRC_PO !! 1649                 if (op->src.type != OP_SRC_POP) {
3298                         WARN_INSN(insn, "unkn !! 1650                         WARN_FUNC("unknown stack-related memory operation",
                                                   >> 1651                                   insn->sec, insn->offset);
3299                         return -1;               1652                         return -1;
3300                 }                                1653                 }
3301                                                  1654 
3302                 /* pop mem */                    1655                 /* pop mem */
3303                 cfi->stack_size -= 8;         !! 1656                 state->stack_size -= 8;
3304                 if (cfa->base == CFI_SP)         1657                 if (cfa->base == CFI_SP)
3305                         cfa->offset -= 8;        1658                         cfa->offset -= 8;
3306                                                  1659 
3307                 break;                           1660                 break;
3308                                                  1661 
3309         default:                                 1662         default:
3310                 WARN_INSN(insn, "unknown stac !! 1663                 WARN_FUNC("unknown stack-related instruction",
3311                 return -1;                    !! 1664                           insn->sec, insn->offset);
3312         }                                     << 
3313                                               << 
3314         return 0;                             << 
3315 }                                             << 
3316                                               << 
3317 /*                                            << 
3318  * The stack layouts of alternatives instruct << 
3319  * they have stack modifications.  That's fin << 
3320  * layouts don't conflict at any given potent << 
3321  *                                            << 
3322  * Flatten the CFIs of the different alternat << 
3323  * and replacement) into a single shared CFI  << 
3324  * conflicts and nicely feed a linear array o << 
3325  */                                           << 
3326 static int propagate_alt_cfi(struct objtool_f << 
3327 {                                             << 
3328         struct cfi_state **alt_cfi;           << 
3329         int group_off;                        << 
3330                                               << 
3331         if (!insn->alt_group)                 << 
3332                 return 0;                     << 
3333                                               << 
3334         if (!insn->cfi) {                     << 
3335                 WARN("CFI missing");          << 
3336                 return -1;                       1665                 return -1;
3337         }                                        1666         }
3338                                                  1667 
3339         alt_cfi = insn->alt_group->cfi;       << 
3340         group_off = insn->offset - insn->alt_ << 
3341                                               << 
3342         if (!alt_cfi[group_off]) {            << 
3343                 alt_cfi[group_off] = insn->cf << 
3344         } else {                              << 
3345                 if (cficmp(alt_cfi[group_off] << 
3346                         struct alt_group *ori << 
3347                         struct instruction *o << 
3348                         char *where = offstr( << 
3349                         WARN_INSN(orig, "stac << 
3350                         free(where);          << 
3351                         return -1;            << 
3352                 }                             << 
3353         }                                     << 
3354                                               << 
3355         return 0;                                1668         return 0;
3356 }                                                1669 }
3357                                                  1670 
3358 static int handle_insn_ops(struct instruction !! 1671 static bool insn_state_match(struct instruction *insn, struct insn_state *state)
3359                            struct instruction << 
3360                            struct insn_state  << 
3361 {                                                1672 {
3362         struct stack_op *op;                  !! 1673         struct insn_state *state1 = &insn->state, *state2 = state;
3363                                               << 
3364         for (op = insn->stack_ops; op; op = o << 
3365                                               << 
3366                 if (update_cfi_state(insn, ne << 
3367                         return 1;             << 
3368                                               << 
3369                 if (!insn->alt_group)         << 
3370                         continue;             << 
3371                                               << 
3372                 if (op->dest.type == OP_DEST_ << 
3373                         if (!state->uaccess_s << 
3374                                 state->uacces << 
3375                         } else if (state->uac << 
3376                                 WARN_INSN(ins << 
3377                                 return 1;     << 
3378                         }                     << 
3379                         state->uaccess_stack  << 
3380                         state->uaccess_stack  << 
3381                 }                             << 
3382                                               << 
3383                 if (op->src.type == OP_SRC_PO << 
3384                         if (state->uaccess_st << 
3385                                 state->uacces << 
3386                                 state->uacces << 
3387                                 if (state->ua << 
3388                                         state << 
3389                         }                     << 
3390                 }                             << 
3391         }                                     << 
3392                                               << 
3393         return 0;                             << 
3394 }                                             << 
3395                                               << 
3396 static bool insn_cfi_match(struct instruction << 
3397 {                                             << 
3398         struct cfi_state *cfi1 = insn->cfi;   << 
3399         int i;                                   1674         int i;
3400                                                  1675 
3401         if (!cfi1) {                          !! 1676         if (memcmp(&state1->cfa, &state2->cfa, sizeof(state1->cfa))) {
3402                 WARN("CFI missing");          !! 1677                 WARN_FUNC("stack state mismatch: cfa1=%d%+d cfa2=%d%+d",
3403                 return false;                 !! 1678                           insn->sec, insn->offset,
3404         }                                     !! 1679                           state1->cfa.base, state1->cfa.offset,
                                                   >> 1680                           state2->cfa.base, state2->cfa.offset);
3405                                                  1681 
3406         if (memcmp(&cfi1->cfa, &cfi2->cfa, si !! 1682         } else if (memcmp(&state1->regs, &state2->regs, sizeof(state1->regs))) {
3407                                               << 
3408                 WARN_INSN(insn, "stack state  << 
3409                           cfi1->cfa.base, cfi << 
3410                           cfi2->cfa.base, cfi << 
3411                                               << 
3412         } else if (memcmp(&cfi1->regs, &cfi2- << 
3413                 for (i = 0; i < CFI_NUM_REGS;    1683                 for (i = 0; i < CFI_NUM_REGS; i++) {
3414                         if (!memcmp(&cfi1->re !! 1684                         if (!memcmp(&state1->regs[i], &state2->regs[i],
3415                                     sizeof(st    1685                                     sizeof(struct cfi_reg)))
3416                                 continue;        1686                                 continue;
3417                                                  1687 
3418                         WARN_INSN(insn, "stac !! 1688                         WARN_FUNC("stack state mismatch: reg1[%d]=%d%+d reg2[%d]=%d%+d",
3419                                   i, cfi1->re !! 1689                                   insn->sec, insn->offset,
3420                                   i, cfi2->re !! 1690                                   i, state1->regs[i].base, state1->regs[i].offset,
                                                   >> 1691                                   i, state2->regs[i].base, state2->regs[i].offset);
3421                         break;                   1692                         break;
3422                 }                                1693                 }
3423                                                  1694 
3424         } else if (cfi1->type != cfi2->type)  !! 1695         } else if (state1->type != state2->type) {
3425                                               !! 1696                 WARN_FUNC("stack state mismatch: type1=%d type2=%d",
3426                 WARN_INSN(insn, "stack state  !! 1697                           insn->sec, insn->offset, state1->type, state2->type);
3427                           cfi1->type, cfi2->t !! 1698 
3428                                               !! 1699         } else if (state1->drap != state2->drap ||
3429         } else if (cfi1->drap != cfi2->drap | !! 1700                  (state1->drap && state1->drap_reg != state2->drap_reg) ||
3430                    (cfi1->drap && cfi1->drap_ !! 1701                  (state1->drap && state1->drap_offset != state2->drap_offset)) {
3431                    (cfi1->drap && cfi1->drap_ !! 1702                 WARN_FUNC("stack state mismatch: drap1=%d(%d,%d) drap2=%d(%d,%d)",
3432                                               !! 1703                           insn->sec, insn->offset,
3433                 WARN_INSN(insn, "stack state  !! 1704                           state1->drap, state1->drap_reg, state1->drap_offset,
3434                           cfi1->drap, cfi1->d !! 1705                           state2->drap, state2->drap_reg, state2->drap_offset);
3435                           cfi2->drap, cfi2->d << 
3436                                                  1706 
3437         } else                                   1707         } else
3438                 return true;                     1708                 return true;
3439                                                  1709 
3440         return false;                            1710         return false;
3441 }                                                1711 }
3442                                                  1712 
3443 static inline bool func_uaccess_safe(struct s << 
3444 {                                             << 
3445         if (func)                             << 
3446                 return func->uaccess_safe;    << 
3447                                               << 
3448         return false;                         << 
3449 }                                             << 
3450                                               << 
3451 static inline const char *call_dest_name(stru << 
3452 {                                             << 
3453         static char pvname[19];               << 
3454         struct reloc *reloc;                  << 
3455         int idx;                              << 
3456                                               << 
3457         if (insn_call_dest(insn))             << 
3458                 return insn_call_dest(insn)-> << 
3459                                               << 
3460         reloc = insn_reloc(NULL, insn);       << 
3461         if (reloc && !strcmp(reloc->sym->name << 
3462                 idx = (reloc_addend(reloc) /  << 
3463                 snprintf(pvname, sizeof(pvnam << 
3464                 return pvname;                << 
3465         }                                     << 
3466                                               << 
3467         return "{dynamic}";                   << 
3468 }                                             << 
3469                                               << 
3470 static bool pv_call_dest(struct objtool_file  << 
3471 {                                             << 
3472         struct symbol *target;                << 
3473         struct reloc *reloc;                  << 
3474         int idx;                              << 
3475                                               << 
3476         reloc = insn_reloc(file, insn);       << 
3477         if (!reloc || strcmp(reloc->sym->name << 
3478                 return false;                 << 
3479                                               << 
3480         idx = (arch_dest_reloc_offset(reloc_a << 
3481                                               << 
3482         if (file->pv_ops[idx].clean)          << 
3483                 return true;                  << 
3484                                               << 
3485         file->pv_ops[idx].clean = true;       << 
3486                                               << 
3487         list_for_each_entry(target, &file->pv << 
3488                 if (!target->sec->noinstr) {  << 
3489                         WARN("pv_ops[%d]: %s" << 
3490                         file->pv_ops[idx].cle << 
3491                 }                             << 
3492         }                                     << 
3493                                               << 
3494         return file->pv_ops[idx].clean;       << 
3495 }                                             << 
3496                                               << 
3497 static inline bool noinstr_call_dest(struct o << 
3498                                      struct i << 
3499                                      struct s << 
3500 {                                             << 
3501         /*                                    << 
3502          * We can't deal with indirect functi << 
3503          * assume they're instrumented.       << 
3504          */                                   << 
3505         if (!func) {                          << 
3506                 if (file->pv_ops)             << 
3507                         return pv_call_dest(f << 
3508                                               << 
3509                 return false;                 << 
3510         }                                     << 
3511                                               << 
3512         /*                                    << 
3513          * If the symbol is from a noinstr se << 
3514          */                                   << 
3515         if (func->sec->noinstr)               << 
3516                 return true;                  << 
3517                                               << 
3518         /*                                    << 
3519          * If the symbol is a static_call tra << 
3520          */                                   << 
3521         if (func->static_call_tramp)          << 
3522                 return true;                  << 
3523                                               << 
3524         /*                                    << 
3525          * The __ubsan_handle_*() calls are l << 
3526          * something 'BAD' happened. At the r << 
3527          * let them proceed to get the messag << 
3528          */                                   << 
3529         if (!strncmp(func->name, "__ubsan_han << 
3530                 return true;                  << 
3531                                               << 
3532         return false;                         << 
3533 }                                             << 
3534                                               << 
3535 static int validate_call(struct objtool_file  << 
3536                          struct instruction * << 
3537                          struct insn_state *s << 
3538 {                                             << 
3539         if (state->noinstr && state->instr <= << 
3540             !noinstr_call_dest(file, insn, in << 
3541                 WARN_INSN(insn, "call to %s() << 
3542                 return 1;                     << 
3543         }                                     << 
3544                                               << 
3545         if (state->uaccess && !func_uaccess_s << 
3546                 WARN_INSN(insn, "call to %s() << 
3547                 return 1;                     << 
3548         }                                     << 
3549                                               << 
3550         if (state->df) {                      << 
3551                 WARN_INSN(insn, "call to %s() << 
3552                 return 1;                     << 
3553         }                                     << 
3554                                               << 
3555         return 0;                             << 
3556 }                                             << 
3557                                               << 
3558 static int validate_sibling_call(struct objto << 
3559                                  struct instr << 
3560                                  struct insn_ << 
3561 {                                             << 
3562         if (insn_func(insn) && has_modified_s << 
3563                 WARN_INSN(insn, "sibling call << 
3564                 return 1;                     << 
3565         }                                     << 
3566                                               << 
3567         return validate_call(file, insn, stat << 
3568 }                                             << 
3569                                               << 
3570 static int validate_return(struct symbol *fun << 
3571 {                                             << 
3572         if (state->noinstr && state->instr >  << 
3573                 WARN_INSN(insn, "return with  << 
3574                 return 1;                     << 
3575         }                                     << 
3576                                               << 
3577         if (state->uaccess && !func_uaccess_s << 
3578                 WARN_INSN(insn, "return with  << 
3579                 return 1;                     << 
3580         }                                     << 
3581                                               << 
3582         if (!state->uaccess && func_uaccess_s << 
3583                 WARN_INSN(insn, "return with  << 
3584                 return 1;                     << 
3585         }                                     << 
3586                                               << 
3587         if (state->df) {                      << 
3588                 WARN_INSN(insn, "return with  << 
3589                 return 1;                     << 
3590         }                                     << 
3591                                               << 
3592         if (func && has_modified_stack_frame( << 
3593                 WARN_INSN(insn, "return with  << 
3594                 return 1;                     << 
3595         }                                     << 
3596                                               << 
3597         if (state->cfi.bp_scratch) {          << 
3598                 WARN_INSN(insn, "BP used as a << 
3599                 return 1;                     << 
3600         }                                     << 
3601                                               << 
3602         return 0;                             << 
3603 }                                             << 
3604                                               << 
3605 static struct instruction *next_insn_to_valid << 
3606                                               << 
3607 {                                             << 
3608         struct alt_group *alt_group = insn->a << 
3609                                               << 
3610         /*                                    << 
3611          * Simulate the fact that alternative << 
3612          * end of a replacement alt_group is  << 
3613          * the end of the original alt_group. << 
3614          *                                    << 
3615          * insn->alts->insn -> alt_group->fir << 
3616          *                     ...            << 
3617          *                     alt_group->las << 
3618          *                     [alt_group->no << 
3619          */                                   << 
3620         if (alt_group) {                      << 
3621                 if (alt_group->nop) {         << 
3622                         /* ->nop implies ->or << 
3623                         if (insn == alt_group << 
3624                                 return alt_gr << 
3625                         if (insn == alt_group << 
3626                                 goto next_ori << 
3627                 }                             << 
3628                 if (insn == alt_group->last_i << 
3629                         goto next_orig;       << 
3630         }                                     << 
3631                                               << 
3632         return next_insn_same_sec(file, insn) << 
3633                                               << 
3634 next_orig:                                    << 
3635         return next_insn_same_sec(file, alt_g << 
3636 }                                             << 
3637                                               << 
3638 /*                                               1713 /*
3639  * Follow the branch starting at the given in    1714  * Follow the branch starting at the given instruction, and recursively follow
3640  * any other branches (jumps).  Meanwhile, tr    1715  * any other branches (jumps).  Meanwhile, track the frame pointer state at
3641  * each instruction and validate all the rule    1716  * each instruction and validate all the rules described in
3642  * tools/objtool/Documentation/objtool.txt.   !! 1717  * tools/objtool/Documentation/stack-validation.txt.
3643  */                                              1718  */
3644 static int validate_branch(struct objtool_fil !! 1719 static int validate_branch(struct objtool_file *file, struct instruction *first,
3645                            struct instruction !! 1720                            struct insn_state state)
3646 {                                                1721 {
3647         struct alternative *alt;                 1722         struct alternative *alt;
3648         struct instruction *next_insn, *prev_ !! 1723         struct instruction *insn, *next_insn;
3649         struct section *sec;                     1724         struct section *sec;
3650         u8 visited;                           !! 1725         struct symbol *func = NULL;
3651         int ret;                                 1726         int ret;
3652                                                  1727 
                                                   >> 1728         insn = first;
3653         sec = insn->sec;                         1729         sec = insn->sec;
3654                                                  1730 
                                                   >> 1731         if (insn->alt_group && list_empty(&insn->alts)) {
                                                   >> 1732                 WARN_FUNC("don't know how to handle branch to middle of alternative instruction group",
                                                   >> 1733                           sec, insn->offset);
                                                   >> 1734                 return 1;
                                                   >> 1735         }
                                                   >> 1736 
3655         while (1) {                              1737         while (1) {
3656                 next_insn = next_insn_to_vali !! 1738                 next_insn = next_insn_same_sec(file, insn);
3657                                                  1739 
3658                 if (func && insn_func(insn) & << 
3659                         /* Ignore KCFI type p << 
3660                         if (!strncmp(func->na << 
3661                             !strncmp(func->na << 
3662                                 return 0;     << 
3663                                                  1740 
                                                   >> 1741                 if (file->c_file && func && insn->func && func != insn->func) {
3664                         WARN("%s() falls thro    1742                         WARN("%s() falls through to next function %s()",
3665                              func->name, insn !! 1743                              func->name, insn->func->name);
3666                         return 1;                1744                         return 1;
3667                 }                                1745                 }
3668                                                  1746 
                                                   >> 1747                 if (insn->func)
                                                   >> 1748                         func = insn->func;
                                                   >> 1749 
3669                 if (func && insn->ignore) {      1750                 if (func && insn->ignore) {
3670                         WARN_INSN(insn, "BUG: !! 1751                         WARN_FUNC("BUG: why am I validating an ignored function?",
                                                   >> 1752                                   sec, insn->offset);
3671                         return 1;                1753                         return 1;
3672                 }                                1754                 }
3673                                                  1755 
3674                 visited = VISITED_BRANCH << s !! 1756                 if (insn->visited) {
3675                 if (insn->visited & VISITED_B !! 1757                         if (!insn->hint && !insn_state_match(insn, &state))
3676                         if (!insn->hint && !i << 
3677                                 return 1;        1758                                 return 1;
3678                                                  1759 
3679                         if (insn->visited & v !! 1760                         return 0;
3680                                 return 0;     << 
3681                 } else {                      << 
3682                         nr_insns_visited++;   << 
3683                 }                                1761                 }
3684                                                  1762 
3685                 if (state.noinstr)            << 
3686                         state.instr += insn-> << 
3687                                               << 
3688                 if (insn->hint) {                1763                 if (insn->hint) {
3689                         if (insn->restore) {     1764                         if (insn->restore) {
3690                                 struct instru    1765                                 struct instruction *save_insn, *i;
3691                                                  1766 
3692                                 i = insn;        1767                                 i = insn;
3693                                 save_insn = N    1768                                 save_insn = NULL;
3694                                               !! 1769                                 func_for_each_insn_continue_reverse(file, func, i) {
3695                                 sym_for_each_ << 
3696                                         if (i    1770                                         if (i->save) {
3697                                                  1771                                                 save_insn = i;
3698                                                  1772                                                 break;
3699                                         }        1773                                         }
3700                                 }                1774                                 }
3701                                                  1775 
3702                                 if (!save_ins    1776                                 if (!save_insn) {
3703                                         WARN_ !! 1777                                         WARN_FUNC("no corresponding CFI save for CFI restore",
                                                   >> 1778                                                   sec, insn->offset);
3704                                         retur    1779                                         return 1;
3705                                 }                1780                                 }
3706                                                  1781 
3707                                 if (!save_ins    1782                                 if (!save_insn->visited) {
3708                                         /*       1783                                         /*
3709                                          * If !! 1784                                          * Oops, no state to copy yet.
3710                                          * be !! 1785                                          * Hopefully we can reach this
3711                                          * br !! 1786                                          * instruction from another branch
3712                                          * sa !! 1787                                          * after the save insn has been
3713                                          * de !! 1788                                          * visited.
3714                                          * It << 
3715                                          * st << 
3716                                          */      1789                                          */
3717                                         if (! !! 1790                                         if (insn == first)
3718                                                  1791                                                 return 0;
3719                                                  1792 
3720                                         WARN_ !! 1793                                         WARN_FUNC("objtool isn't smart enough to handle this CFI save/restore combo",
                                                   >> 1794                                                   sec, insn->offset);
3721                                         retur    1795                                         return 1;
3722                                 }                1796                                 }
3723                                                  1797 
3724                                 insn->cfi = s !! 1798                                 insn->state = save_insn->state;
3725                                 nr_cfi_reused << 
3726                         }                        1799                         }
3727                                                  1800 
3728                         state.cfi = *insn->cf !! 1801                         state = insn->state;
3729                 } else {                      << 
3730                         /* XXX track if we ac << 
3731                                                  1802 
3732                         if (prev_insn && !cfi !! 1803                 } else
3733                                 insn->cfi = p !! 1804                         insn->state = state;
3734                                 nr_cfi_reused << 
3735                         } else {              << 
3736                                 insn->cfi = c << 
3737                         }                     << 
3738                 }                             << 
3739                                               << 
3740                 insn->visited |= visited;     << 
3741                                               << 
3742                 if (propagate_alt_cfi(file, i << 
3743                         return 1;             << 
3744                                                  1805 
3745                 if (!insn->ignore_alts && ins !! 1806                 insn->visited = true;
3746                         bool skip_orig = fals << 
3747                                                  1807 
3748                         for (alt = insn->alts !! 1808                 if (!insn->ignore_alts) {
3749                                 if (alt->skip !! 1809                         list_for_each_entry(alt, &insn->alts, list) {
3750                                         skip_ !! 1810                                 ret = validate_branch(file, alt->insn, state);
3751                                               !! 1811                                 if (ret)
3752                                 ret = validat !! 1812                                         return 1;
3753                                 if (ret) {    << 
3754                                         BT_IN << 
3755                                         retur << 
3756                                 }             << 
3757                         }                        1813                         }
3758                                               << 
3759                         if (skip_orig)        << 
3760                                 return 0;     << 
3761                 }                                1814                 }
3762                                                  1815 
3763                 if (handle_insn_ops(insn, nex << 
3764                         return 1;             << 
3765                                               << 
3766                 switch (insn->type) {            1816                 switch (insn->type) {
3767                                                  1817 
3768                 case INSN_RETURN:                1818                 case INSN_RETURN:
3769                         return validate_retur !! 1819                         if (func && has_modified_stack_frame(&state)) {
3770                                               !! 1820                                 WARN_FUNC("return with modified stack frame",
3771                 case INSN_CALL:               !! 1821                                           sec, insn->offset);
3772                 case INSN_CALL_DYNAMIC:       !! 1822                                 return 1;
3773                         ret = validate_call(f !! 1823                         }
3774                         if (ret)              << 
3775                                 return ret;   << 
3776                                                  1824 
3777                         if (opts.stackval &&  !! 1825                         if (state.bp_scratch) {
3778                             !has_valid_stack_ !! 1826                                 WARN("%s uses BP as a scratch register",
3779                                 WARN_INSN(ins !! 1827                                      insn->func->name);
3780                                 return 1;        1828                                 return 1;
3781                         }                        1829                         }
3782                                                  1830 
3783                         if (insn->dead_end)   !! 1831                         return 0;
                                                   >> 1832 
                                                   >> 1833                 case INSN_CALL:
                                                   >> 1834                         if (is_fentry_call(insn))
                                                   >> 1835                                 break;
                                                   >> 1836 
                                                   >> 1837                         ret = dead_end_function(file, insn->call_dest);
                                                   >> 1838                         if (ret == 1)
3784                                 return 0;        1839                                 return 0;
                                                   >> 1840                         if (ret == -1)
                                                   >> 1841                                 return 1;
3785                                                  1842 
                                                   >> 1843                         /* fallthrough */
                                                   >> 1844                 case INSN_CALL_DYNAMIC:
                                                   >> 1845                         if (!no_fp && func && !has_valid_stack_frame(&state)) {
                                                   >> 1846                                 WARN_FUNC("call without frame pointer save/setup",
                                                   >> 1847                                           sec, insn->offset);
                                                   >> 1848                                 return 1;
                                                   >> 1849                         }
3786                         break;                   1850                         break;
3787                                                  1851 
3788                 case INSN_JUMP_CONDITIONAL:      1852                 case INSN_JUMP_CONDITIONAL:
3789                 case INSN_JUMP_UNCONDITIONAL:    1853                 case INSN_JUMP_UNCONDITIONAL:
3790                         if (is_sibling_call(i !! 1854                         if (insn->jump_dest &&
3791                                 ret = validat !! 1855                             (!func || !insn->jump_dest->func ||
                                                   >> 1856                              func == insn->jump_dest->func)) {
                                                   >> 1857                                 ret = validate_branch(file, insn->jump_dest,
                                                   >> 1858                                                       state);
3792                                 if (ret)         1859                                 if (ret)
3793                                         retur !! 1860                                         return 1;
3794                                                  1861 
3795                         } else if (insn->jump !! 1862                         } else if (func && has_modified_stack_frame(&state)) {
3796                                 ret = validat !! 1863                                 WARN_FUNC("sibling call from callable instruction with modified stack frame",
3797                                               !! 1864                                           sec, insn->offset);
3798                                 if (ret) {    !! 1865                                 return 1;
3799                                         BT_IN << 
3800                                         retur << 
3801                                 }             << 
3802                         }                        1866                         }
3803                                                  1867 
3804                         if (insn->type == INS    1868                         if (insn->type == INSN_JUMP_UNCONDITIONAL)
3805                                 return 0;        1869                                 return 0;
3806                                                  1870 
3807                         break;                   1871                         break;
3808                                                  1872 
3809                 case INSN_JUMP_DYNAMIC:          1873                 case INSN_JUMP_DYNAMIC:
3810                 case INSN_JUMP_DYNAMIC_CONDIT !! 1874                         if (func && list_empty(&insn->alts) &&
3811                         if (is_sibling_call(i !! 1875                             has_modified_stack_frame(&state)) {
3812                                 ret = validat !! 1876                                 WARN_FUNC("sibling call from callable instruction with modified stack frame",
3813                                 if (ret)      !! 1877                                           sec, insn->offset);
3814                                         retur !! 1878                                 return 1;
3815                         }                        1879                         }
3816                                                  1880 
3817                         if (insn->type == INS !! 1881                         return 0;
3818                                 return 0;     << 
3819                                               << 
3820                         break;                << 
3821                                                  1882 
3822                 case INSN_CONTEXT_SWITCH:        1883                 case INSN_CONTEXT_SWITCH:
3823                         if (func && (!next_in    1884                         if (func && (!next_insn || !next_insn->hint)) {
3824                                 WARN_INSN(ins !! 1885                                 WARN_FUNC("unsupported instruction in callable function",
                                                   >> 1886                                           sec, insn->offset);
3825                                 return 1;        1887                                 return 1;
3826                         }                        1888                         }
3827                         return 0;                1889                         return 0;
3828                                                  1890 
3829                 case INSN_STAC:               !! 1891                 case INSN_STACK:
3830                         if (state.uaccess) {  !! 1892                         if (update_insn_state(insn, &state))
3831                                 WARN_INSN(ins << 
3832                                 return 1;        1893                                 return 1;
3833                         }                     << 
3834                                                  1894 
3835                         state.uaccess = true; << 
3836                         break;                << 
3837                                               << 
3838                 case INSN_CLAC:               << 
3839                         if (!state.uaccess && << 
3840                                 WARN_INSN(ins << 
3841                                 return 1;     << 
3842                         }                     << 
3843                                               << 
3844                         if (func_uaccess_safe << 
3845                                 WARN_INSN(ins << 
3846                                 return 1;     << 
3847                         }                     << 
3848                                               << 
3849                         state.uaccess = false << 
3850                         break;                << 
3851                                               << 
3852                 case INSN_STD:                << 
3853                         if (state.df) {       << 
3854                                 WARN_INSN(ins << 
3855                                 return 1;     << 
3856                         }                     << 
3857                                               << 
3858                         state.df = true;      << 
3859                         break;                << 
3860                                               << 
3861                 case INSN_CLD:                << 
3862                         if (!state.df && func << 
3863                                 WARN_INSN(ins << 
3864                                 return 1;     << 
3865                         }                     << 
3866                                               << 
3867                         state.df = false;     << 
3868                         break;                   1895                         break;
3869                                                  1896 
3870                 default:                         1897                 default:
3871                         break;                   1898                         break;
3872                 }                                1899                 }
3873                                                  1900 
3874                 if (insn->dead_end)              1901                 if (insn->dead_end)
3875                         return 0;                1902                         return 0;
3876                                                  1903 
3877                 if (!next_insn) {                1904                 if (!next_insn) {
3878                         if (state.cfi.cfa.bas !! 1905                         if (state.cfa.base == CFI_UNDEFINED)
3879                                 return 0;        1906                                 return 0;
3880                         WARN("%s: unexpected     1907                         WARN("%s: unexpected end of section", sec->name);
3881                         return 1;                1908                         return 1;
3882                 }                                1909                 }
3883                                                  1910 
3884                 prev_insn = insn;             << 
3885                 insn = next_insn;                1911                 insn = next_insn;
3886         }                                        1912         }
3887                                                  1913 
3888         return 0;                                1914         return 0;
3889 }                                                1915 }
3890                                                  1916 
3891 static int validate_unwind_hint(struct objtoo !! 1917 static int validate_unwind_hints(struct objtool_file *file)
3892                                   struct inst << 
3893                                   struct insn << 
3894 {                                             << 
3895         if (insn->hint && !insn->visited && ! << 
3896                 int ret = validate_branch(fil << 
3897                 if (ret)                      << 
3898                         BT_INSN(insn, "<=== ( << 
3899                 return ret;                   << 
3900         }                                     << 
3901                                               << 
3902         return 0;                             << 
3903 }                                             << 
3904                                               << 
3905 static int validate_unwind_hints(struct objto << 
3906 {                                                1918 {
3907         struct instruction *insn;                1919         struct instruction *insn;
                                                   >> 1920         int ret, warnings = 0;
3908         struct insn_state state;                 1921         struct insn_state state;
3909         int warnings = 0;                     << 
3910                                                  1922 
3911         if (!file->hints)                        1923         if (!file->hints)
3912                 return 0;                        1924                 return 0;
3913                                                  1925 
3914         init_insn_state(file, &state, sec);   !! 1926         clear_insn_state(&state);
3915                                               << 
3916         if (sec) {                            << 
3917                 sec_for_each_insn(file, sec,  << 
3918                         warnings += validate_ << 
3919         } else {                              << 
3920                 for_each_insn(file, insn)     << 
3921                         warnings += validate_ << 
3922         }                                     << 
3923                                               << 
3924         return warnings;                      << 
3925 }                                             << 
3926                                               << 
3927 /*                                            << 
3928  * Validate rethunk entry constraint: must un << 
3929  *                                            << 
3930  * Follow every branch (intra-function) and e << 
3931  * before an actual RET instruction.          << 
3932  */                                           << 
3933 static int validate_unret(struct objtool_file << 
3934 {                                             << 
3935         struct instruction *next, *dest;      << 
3936         int ret;                              << 
3937                                               << 
3938         for (;;) {                            << 
3939                 next = next_insn_to_validate( << 
3940                                               << 
3941                 if (insn->visited & VISITED_U << 
3942                         return 0;             << 
3943                                               << 
3944                 insn->visited |= VISITED_UNRE << 
3945                                               << 
3946                 if (!insn->ignore_alts && ins << 
3947                         struct alternative *a << 
3948                         bool skip_orig = fals << 
3949                                               << 
3950                         for (alt = insn->alts << 
3951                                 if (alt->skip << 
3952                                         skip_ << 
3953                                               << 
3954                                 ret = validat << 
3955                                 if (ret) {    << 
3956                                         BT_IN << 
3957                                         retur << 
3958                                 }             << 
3959                         }                     << 
3960                                               << 
3961                         if (skip_orig)        << 
3962                                 return 0;     << 
3963                 }                             << 
3964                                               << 
3965                 switch (insn->type) {         << 
3966                                               << 
3967                 case INSN_CALL_DYNAMIC:       << 
3968                 case INSN_JUMP_DYNAMIC:       << 
3969                 case INSN_JUMP_DYNAMIC_CONDIT << 
3970                         WARN_INSN(insn, "earl << 
3971                         return 1;             << 
3972                                               << 
3973                 case INSN_JUMP_UNCONDITIONAL: << 
3974                 case INSN_JUMP_CONDITIONAL:   << 
3975                         if (!is_sibling_call( << 
3976                                 if (!insn->ju << 
3977                                         WARN_ << 
3978                                         retur << 
3979                                 }             << 
3980                                 ret = validat << 
3981                                 if (ret) {    << 
3982                                         BT_IN << 
3983                                               << 
3984                                         retur << 
3985                                 }             << 
3986                                               << 
3987                                 if (insn->typ << 
3988                                         retur << 
3989                                               << 
3990                                 break;        << 
3991                         }                     << 
3992                                               << 
3993                         /* fallthrough */     << 
3994                 case INSN_CALL:               << 
3995                         dest = find_insn(file << 
3996                                          insn << 
3997                         if (!dest) {          << 
3998                                 WARN("Unresol << 
3999                                      insn_cal << 
4000                                 return -1;    << 
4001                         }                     << 
4002                                               << 
4003                         ret = validate_unret( << 
4004                         if (ret) {            << 
4005                                 BT_INSN(insn, << 
4006                                 return ret;   << 
4007                         }                     << 
4008                         /*                    << 
4009                          * If a call returns  << 
4010                          * Therefore any non- << 
4011                          */                   << 
4012                         return 0;             << 
4013                                               << 
4014                 case INSN_RETURN:             << 
4015                         WARN_INSN(insn, "RET  << 
4016                         return 1;             << 
4017                                               << 
4018                 case INSN_NOP:                << 
4019                         if (insn->retpoline_s << 
4020                                 return 0;     << 
4021                         break;                << 
4022                                               << 
4023                 default:                      << 
4024                         break;                << 
4025                 }                             << 
4026                                               << 
4027                 if (!next) {                  << 
4028                         WARN_INSN(insn, "teh  << 
4029                         return -1;            << 
4030                 }                             << 
4031                 insn = next;                  << 
4032         }                                     << 
4033                                               << 
4034         return 0;                             << 
4035 }                                             << 
4036                                               << 
4037 /*                                            << 
4038  * Validate that all branches starting at VAL << 
4039  * VALIDATE_UNRET_END before RET.             << 
4040  */                                           << 
4041 static int validate_unrets(struct objtool_fil << 
4042 {                                             << 
4043         struct instruction *insn;             << 
4044         int ret, warnings = 0;                << 
4045                                                  1927 
4046         for_each_insn(file, insn) {              1928         for_each_insn(file, insn) {
4047                 if (!insn->unret)             !! 1929                 if (insn->hint && !insn->visited) {
4048                         continue;             !! 1930                         ret = validate_branch(file, insn, state);
4049                                               !! 1931                         warnings += ret;
4050                 ret = validate_unret(file, in << 
4051                 if (ret < 0) {                << 
4052                         WARN_INSN(insn, "Fail << 
4053                         return ret;           << 
4054                 }                                1932                 }
4055                 warnings += ret;              << 
4056         }                                        1933         }
4057                                                  1934 
4058         return warnings;                         1935         return warnings;
4059 }                                                1936 }
4060                                                  1937 
4061 static int validate_retpoline(struct objtool_    1938 static int validate_retpoline(struct objtool_file *file)
4062 {                                                1939 {
4063         struct instruction *insn;                1940         struct instruction *insn;
4064         int warnings = 0;                        1941         int warnings = 0;
4065                                                  1942 
4066         for_each_insn(file, insn) {              1943         for_each_insn(file, insn) {
4067                 if (insn->type != INSN_JUMP_D    1944                 if (insn->type != INSN_JUMP_DYNAMIC &&
4068                     insn->type != INSN_CALL_D !! 1945                     insn->type != INSN_CALL_DYNAMIC)
4069                     insn->type != INSN_RETURN << 
4070                         continue;                1946                         continue;
4071                                                  1947 
4072                 if (insn->retpoline_safe)        1948                 if (insn->retpoline_safe)
4073                         continue;                1949                         continue;
4074                                                  1950 
4075                 if (insn->sec->init)          !! 1951                 /*
                                                   >> 1952                  * .init.text code is ran before userspace and thus doesn't
                                                   >> 1953                  * strictly need retpolines, except for modules which are
                                                   >> 1954                  * loaded late, they very much do need retpoline in their
                                                   >> 1955                  * .init.text
                                                   >> 1956                  */
                                                   >> 1957                 if (!strcmp(insn->sec->name, ".init.text") && !module)
4076                         continue;                1958                         continue;
4077                                                  1959 
4078                 if (insn->type == INSN_RETURN !! 1960                 WARN_FUNC("indirect %s found in RETPOLINE build",
4079                         if (opts.rethunk) {   !! 1961                           insn->sec, insn->offset,
4080                                 WARN_INSN(ins !! 1962                           insn->type == INSN_JUMP_DYNAMIC ? "jump" : "call");
4081                         } else                << 
4082                                 continue;     << 
4083                 } else {                      << 
4084                         WARN_INSN(insn, "indi << 
4085                                   insn->type  << 
4086                 }                             << 
4087                                                  1963 
4088                 warnings++;                      1964                 warnings++;
4089         }                                        1965         }
4090                                                  1966 
4091         return warnings;                         1967         return warnings;
4092 }                                                1968 }
4093                                                  1969 
4094 static bool is_kasan_insn(struct instruction     1970 static bool is_kasan_insn(struct instruction *insn)
4095 {                                                1971 {
4096         return (insn->type == INSN_CALL &&       1972         return (insn->type == INSN_CALL &&
4097                 !strcmp(insn_call_dest(insn)- !! 1973                 !strcmp(insn->call_dest->name, "__asan_handle_no_return"));
4098 }                                                1974 }
4099                                                  1975 
4100 static bool is_ubsan_insn(struct instruction     1976 static bool is_ubsan_insn(struct instruction *insn)
4101 {                                                1977 {
4102         return (insn->type == INSN_CALL &&       1978         return (insn->type == INSN_CALL &&
4103                 !strcmp(insn_call_dest(insn)- !! 1979                 !strcmp(insn->call_dest->name,
4104                         "__ubsan_handle_built    1980                         "__ubsan_handle_builtin_unreachable"));
4105 }                                                1981 }
4106                                                  1982 
4107 static bool ignore_unreachable_insn(struct ob !! 1983 static bool ignore_unreachable_insn(struct instruction *insn)
4108 {                                                1984 {
4109         int i;                                   1985         int i;
4110         struct instruction *prev_insn;        << 
4111                                                  1986 
4112         if (insn->ignore || insn->type == INS !! 1987         if (insn->ignore || insn->type == INSN_NOP)
4113                 return true;                     1988                 return true;
4114                                                  1989 
4115         /*                                       1990         /*
4116          * Ignore alternative replacement ins !! 1991          * Ignore any unused exceptions.  This can happen when a whitelisted
                                                   >> 1992          * function has an exception table entry.
                                                   >> 1993          *
                                                   >> 1994          * Also ignore alternative replacement instructions.  This can happen
4117          * when a whitelisted function uses o    1995          * when a whitelisted function uses one of the ALTERNATIVE macros.
4118          */                                      1996          */
4119         if (!strcmp(insn->sec->name, ".altins !! 1997         if (!strcmp(insn->sec->name, ".fixup") ||
                                                   >> 1998             !strcmp(insn->sec->name, ".altinstr_replacement") ||
4120             !strcmp(insn->sec->name, ".altins    1999             !strcmp(insn->sec->name, ".altinstr_aux"))
4121                 return true;                     2000                 return true;
4122                                                  2001 
4123         /*                                       2002         /*
4124          * Whole archive runs might encounter << 
4125          * This is where the linker will have << 
4126          * favour of a regular symbol, but le << 
4127          *                                    << 
4128          * In this case we'll find a piece of << 
4129          * covered by a !section symbol. Igno << 
4130          */                                   << 
4131         if (opts.link && !insn_func(insn)) {  << 
4132                 int size = find_symbol_hole_c << 
4133                 unsigned long end = insn->off << 
4134                                               << 
4135                 if (!size) /* not a hole */   << 
4136                         return false;         << 
4137                                               << 
4138                 if (size < 0) /* hole until t << 
4139                         return true;          << 
4140                                               << 
4141                 sec_for_each_insn_continue(fi << 
4142                         /*                    << 
4143                          * If we reach a visi << 
4144                          * end of the hole, i << 
4145                          */                   << 
4146                         if (insn->visited)    << 
4147                                 return true;  << 
4148                                               << 
4149                         if (insn->offset >= e << 
4150                                 break;        << 
4151                                               << 
4152                         /*                    << 
4153                          * If this hole jumps << 
4154                          */                   << 
4155                         if (insn->jump_dest & << 
4156                             strstr(insn_func( << 
4157                                 struct instru << 
4158                                 func_for_each << 
4159                                         dest- << 
4160                         }                     << 
4161                 }                             << 
4162                                               << 
4163                 return false;                 << 
4164         }                                     << 
4165                                               << 
4166         if (!insn_func(insn))                 << 
4167                 return false;                 << 
4168                                               << 
4169         if (insn_func(insn)->static_call_tram << 
4170                 return true;                  << 
4171                                               << 
4172         /*                                    << 
4173          * CONFIG_UBSAN_TRAP inserts a UD2 wh << 
4174          * __builtin_unreachable().  The BUG( << 
4175          * the UD2, which causes GCC's undefi << 
4176          * (or occasionally a JMP to UD2).    << 
4177          *                                    << 
4178          * It may also insert a UD2 after cal << 
4179          */                                   << 
4180         prev_insn = prev_insn_same_sec(file,  << 
4181         if (prev_insn->dead_end &&            << 
4182             (insn->type == INSN_BUG ||        << 
4183              (insn->type == INSN_JUMP_UNCONDI << 
4184               insn->jump_dest && insn->jump_d << 
4185                 return true;                  << 
4186                                               << 
4187         /*                                    << 
4188          * Check if this (or a subsequent) in    2003          * Check if this (or a subsequent) instruction is related to
4189          * CONFIG_UBSAN or CONFIG_KASAN.         2004          * CONFIG_UBSAN or CONFIG_KASAN.
4190          *                                       2005          *
4191          * End the search at 5 instructions t    2006          * End the search at 5 instructions to avoid going into the weeds.
4192          */                                      2007          */
                                                   >> 2008         if (!insn->func)
                                                   >> 2009                 return false;
4193         for (i = 0; i < 5; i++) {                2010         for (i = 0; i < 5; i++) {
4194                                                  2011 
4195                 if (is_kasan_insn(insn) || is    2012                 if (is_kasan_insn(insn) || is_ubsan_insn(insn))
4196                         return true;             2013                         return true;
4197                                                  2014 
4198                 if (insn->type == INSN_JUMP_U    2015                 if (insn->type == INSN_JUMP_UNCONDITIONAL) {
4199                         if (insn->jump_dest &    2016                         if (insn->jump_dest &&
4200                             insn_func(insn->j !! 2017                             insn->jump_dest->func == insn->func) {
4201                                 insn = insn->    2018                                 insn = insn->jump_dest;
4202                                 continue;        2019                                 continue;
4203                         }                        2020                         }
4204                                                  2021 
4205                         break;                   2022                         break;
4206                 }                                2023                 }
4207                                                  2024 
4208                 if (insn->offset + insn->len  !! 2025                 if (insn->offset + insn->len >= insn->func->offset + insn->func->len)
4209                         break;                   2026                         break;
4210                                                  2027 
4211                 insn = next_insn_same_sec(fil !! 2028                 insn = list_next_entry(insn, list);
4212         }                                        2029         }
4213                                                  2030 
4214         return false;                            2031         return false;
4215 }                                                2032 }
4216                                                  2033 
4217 static int add_prefix_symbol(struct objtool_f !! 2034 static int validate_functions(struct objtool_file *file)
4218 {                                             << 
4219         struct instruction *insn, *prev;      << 
4220         struct cfi_state *cfi;                << 
4221                                               << 
4222         insn = find_insn(file, func->sec, fun << 
4223         if (!insn)                            << 
4224                 return -1;                    << 
4225                                               << 
4226         for (prev = prev_insn_same_sec(file,  << 
4227              prev;                            << 
4228              prev = prev_insn_same_sec(file,  << 
4229                 u64 offset;                   << 
4230                                               << 
4231                 if (prev->type != INSN_NOP)   << 
4232                         return -1;            << 
4233                                               << 
4234                 offset = func->offset - prev- << 
4235                                               << 
4236                 if (offset > opts.prefix)     << 
4237                         return -1;            << 
4238                                               << 
4239                 if (offset < opts.prefix)     << 
4240                         continue;             << 
4241                                               << 
4242                 elf_create_prefix_symbol(file << 
4243                 break;                        << 
4244         }                                     << 
4245                                               << 
4246         if (!prev)                            << 
4247                 return -1;                    << 
4248                                               << 
4249         if (!insn->cfi) {                     << 
4250                 /*                            << 
4251                  * This can happen if stack v << 
4252                  * function is annotated with << 
4253                  */                           << 
4254                 return 0;                     << 
4255         }                                     << 
4256                                               << 
4257         /* Propagate insn->cfi to the prefix  << 
4258         cfi = cfi_hash_find_or_add(insn->cfi) << 
4259         for (; prev != insn; prev = next_insn << 
4260                 prev->cfi = cfi;              << 
4261                                               << 
4262         return 0;                             << 
4263 }                                             << 
4264                                               << 
4265 static int add_prefix_symbols(struct objtool_ << 
4266 {                                                2035 {
4267         struct section *sec;                     2036         struct section *sec;
4268         struct symbol *func;                     2037         struct symbol *func;
4269                                               << 
4270         for_each_sec(file, sec) {             << 
4271                 if (!(sec->sh.sh_flags & SHF_ << 
4272                         continue;             << 
4273                                               << 
4274                 sec_for_each_sym(sec, func) { << 
4275                         if (func->type != STT << 
4276                                 continue;     << 
4277                                               << 
4278                         add_prefix_symbol(fil << 
4279                 }                             << 
4280         }                                     << 
4281                                               << 
4282         return 0;                             << 
4283 }                                             << 
4284                                               << 
4285 static int validate_symbol(struct objtool_fil << 
4286                            struct symbol *sym << 
4287 {                                             << 
4288         struct instruction *insn;                2038         struct instruction *insn;
4289         int ret;                              << 
4290                                               << 
4291         if (!sym->len) {                      << 
4292                 WARN("%s() is missing an ELF  << 
4293                 return 1;                     << 
4294         }                                     << 
4295                                               << 
4296         if (sym->pfunc != sym || sym->alias ! << 
4297                 return 0;                     << 
4298                                               << 
4299         insn = find_insn(file, sec, sym->offs << 
4300         if (!insn || insn->ignore || insn->vi << 
4301                 return 0;                     << 
4302                                               << 
4303         state->uaccess = sym->uaccess_safe;   << 
4304                                               << 
4305         ret = validate_branch(file, insn_func << 
4306         if (ret)                              << 
4307                 BT_INSN(insn, "<=== (sym)");  << 
4308         return ret;                           << 
4309 }                                             << 
4310                                               << 
4311 static int validate_section(struct objtool_fi << 
4312 {                                             << 
4313         struct insn_state state;                 2039         struct insn_state state;
4314         struct symbol *func;                  !! 2040         int ret, warnings = 0;
4315         int warnings = 0;                     << 
4316                                               << 
4317         sec_for_each_sym(sec, func) {         << 
4318                 if (func->type != STT_FUNC)   << 
4319                         continue;             << 
4320                                               << 
4321                 init_insn_state(file, &state, << 
4322                 set_func_state(&state.cfi);   << 
4323                                               << 
4324                 warnings += validate_symbol(f << 
4325         }                                     << 
4326                                               << 
4327         return warnings;                      << 
4328 }                                             << 
4329                                               << 
4330 static int validate_noinstr_sections(struct o << 
4331 {                                             << 
4332         struct section *sec;                  << 
4333         int warnings = 0;                     << 
4334                                               << 
4335         sec = find_section_by_name(file->elf, << 
4336         if (sec) {                            << 
4337                 warnings += validate_section( << 
4338                 warnings += validate_unwind_h << 
4339         }                                     << 
4340                                               << 
4341         sec = find_section_by_name(file->elf, << 
4342         if (sec) {                            << 
4343                 warnings += validate_section( << 
4344                 warnings += validate_unwind_h << 
4345         }                                     << 
4346                                               << 
4347         sec = find_section_by_name(file->elf, << 
4348         if (sec) {                            << 
4349                 warnings += validate_section( << 
4350                 warnings += validate_unwind_h << 
4351         }                                     << 
4352                                               << 
4353         return warnings;                      << 
4354 }                                             << 
4355                                               << 
4356 static int validate_functions(struct objtool_ << 
4357 {                                             << 
4358         struct section *sec;                  << 
4359         int warnings = 0;                     << 
4360                                               << 
4361         for_each_sec(file, sec) {             << 
4362                 if (!(sec->sh.sh_flags & SHF_ << 
4363                         continue;             << 
4364                                               << 
4365                 warnings += validate_section( << 
4366         }                                     << 
4367                                               << 
4368         return warnings;                      << 
4369 }                                             << 
4370                                               << 
4371 static void mark_endbr_used(struct instructio << 
4372 {                                             << 
4373         if (!list_empty(&insn->call_node))    << 
4374                 list_del_init(&insn->call_nod << 
4375 }                                             << 
4376                                               << 
4377 static bool noendbr_range(struct objtool_file << 
4378 {                                             << 
4379         struct symbol *sym = find_symbol_cont << 
4380         struct instruction *first;            << 
4381                                               << 
4382         if (!sym)                             << 
4383                 return false;                 << 
4384                                               << 
4385         first = find_insn(file, sym->sec, sym << 
4386         if (!first)                           << 
4387                 return false;                 << 
4388                                               << 
4389         if (first->type != INSN_ENDBR && !fir << 
4390                 return false;                 << 
4391                                               << 
4392         return insn->offset == sym->offset +  << 
4393 }                                             << 
4394                                               << 
4395 static int validate_ibt_insn(struct objtool_f << 
4396 {                                             << 
4397         struct instruction *dest;             << 
4398         struct reloc *reloc;                  << 
4399         unsigned long off;                    << 
4400         int warnings = 0;                     << 
4401                                               << 
4402         /*                                    << 
4403          * Looking for function pointer load  << 
4404          * direct/indirect branches:          << 
4405          */                                   << 
4406         switch (insn->type) {                 << 
4407         case INSN_CALL:                       << 
4408         case INSN_CALL_DYNAMIC:               << 
4409         case INSN_JUMP_CONDITIONAL:           << 
4410         case INSN_JUMP_UNCONDITIONAL:         << 
4411         case INSN_JUMP_DYNAMIC:               << 
4412         case INSN_JUMP_DYNAMIC_CONDITIONAL:   << 
4413         case INSN_RETURN:                     << 
4414         case INSN_NOP:                        << 
4415                 return 0;                     << 
4416         default:                              << 
4417                 break;                        << 
4418         }                                     << 
4419                                               << 
4420         for (reloc = insn_reloc(file, insn);  << 
4421              reloc;                           << 
4422              reloc = find_reloc_by_dest_range << 
4423                                               << 
4424                                               << 
4425                                               << 
4426                 /*                            << 
4427                  * static_call_update() refer << 
4428                  * doesn't have (or need) END << 
4429                  */                           << 
4430                 if (reloc->sym->static_call_t << 
4431                         continue;             << 
4432                                               << 
4433                 off = reloc->sym->offset;     << 
4434                 if (reloc_type(reloc) == R_X8 << 
4435                     reloc_type(reloc) == R_X8 << 
4436                         off += arch_dest_relo << 
4437                 else                          << 
4438                         off += reloc_addend(r << 
4439                                               << 
4440                 dest = find_insn(file, reloc- << 
4441                 if (!dest)                    << 
4442                         continue;             << 
4443                                               << 
4444                 if (dest->type == INSN_ENDBR) << 
4445                         mark_endbr_used(dest) << 
4446                         continue;             << 
4447                 }                             << 
4448                                               << 
4449                 if (insn_func(dest) && insn_f << 
4450                     insn_func(dest)->pfunc == << 
4451                         /*                    << 
4452                          * Anything from->to  << 
4453                          * IRET-to-self.      << 
4454                          *                    << 
4455                          * There is no sane w << 
4456                          * compiler treats th << 
4457                          * happy to fold in o << 
4458                          * do, leading to vas << 
4459                          *                    << 
4460                          * There's also compi << 
4461                          * KCOV and such whic << 
4462                          *                    << 
4463                          * As such, blanket a << 
4464                          * issue.             << 
4465                          */                   << 
4466                         continue;             << 
4467                 }                             << 
4468                                               << 
4469                 /*                            << 
4470                  * Accept anything ANNOTATE_N << 
4471                  */                           << 
4472                 if (dest->noendbr)            << 
4473                         continue;             << 
4474                                               << 
4475                 /*                            << 
4476                  * Accept if this is the inst << 
4477                  * that is (no)endbr -- typic << 
4478                  */                           << 
4479                 if (noendbr_range(file, dest) << 
4480                         continue;             << 
4481                                               << 
4482                 WARN_INSN(insn, "relocation t << 
4483                                               << 
4484                 warnings++;                   << 
4485         }                                     << 
4486                                               << 
4487         return warnings;                      << 
4488 }                                             << 
4489                                               << 
4490 static int validate_ibt_data_reloc(struct obj << 
4491                                    struct rel << 
4492 {                                             << 
4493         struct instruction *dest;             << 
4494                                               << 
4495         dest = find_insn(file, reloc->sym->se << 
4496                          reloc->sym->offset + << 
4497         if (!dest)                            << 
4498                 return 0;                     << 
4499                                               << 
4500         if (dest->type == INSN_ENDBR) {       << 
4501                 mark_endbr_used(dest);        << 
4502                 return 0;                     << 
4503         }                                     << 
4504                                               << 
4505         if (dest->noendbr)                    << 
4506                 return 0;                     << 
4507                                               << 
4508         WARN_FUNC("data relocation to !ENDBR: << 
4509                   reloc->sec->base, reloc_off << 
4510                   offstr(dest->sec, dest->off << 
4511                                               << 
4512         return 1;                             << 
4513 }                                             << 
4514                                                  2041 
4515 /*                                            !! 2042         clear_insn_state(&state);
4516  * Validate IBT rules and remove used ENDBR i << 
4517  * Unused ENDBR instructions will be annotate << 
4518  * NOPs) later, in create_ibt_endbr_seal_sect << 
4519  */                                           << 
4520 static int validate_ibt(struct objtool_file * << 
4521 {                                             << 
4522         struct section *sec;                  << 
4523         struct reloc *reloc;                  << 
4524         struct instruction *insn;             << 
4525         int warnings = 0;                     << 
4526                                                  2043 
4527         for_each_insn(file, insn)             !! 2044         state.cfa = initial_func_cfi.cfa;
4528                 warnings += validate_ibt_insn !! 2045         memcpy(&state.regs, &initial_func_cfi.regs,
                                                   >> 2046                CFI_NUM_REGS * sizeof(struct cfi_reg));
                                                   >> 2047         state.stack_size = initial_func_cfi.cfa.offset;
4529                                                  2048 
4530         for_each_sec(file, sec) {                2049         for_each_sec(file, sec) {
                                                   >> 2050                 list_for_each_entry(func, &sec->symbol_list, list) {
                                                   >> 2051                         if (func->type != STT_FUNC)
                                                   >> 2052                                 continue;
4531                                                  2053 
4532                 /* Already done by validate_i !! 2054                         insn = find_insn(file, sec, func->offset);
4533                 if (sec->sh.sh_flags & SHF_EX !! 2055                         if (!insn || insn->ignore)
4534                         continue;             !! 2056                                 continue;
4535                                               << 
4536                 if (!sec->rsec)               << 
4537                         continue;             << 
4538                                               << 
4539                 /*                            << 
4540                  * These sections can referen << 
4541                  * the intent to indirect bra << 
4542                  */                           << 
4543                 if ((!strncmp(sec->name, ".di << 
4544                      strcmp(sec->name, ".disc << 
4545                     !strncmp(sec->name, ".deb << 
4546                     !strcmp(sec->name, ".alti << 
4547                     !strcmp(sec->name, ".ibt_ << 
4548                     !strcmp(sec->name, ".orc_ << 
4549                     !strcmp(sec->name, ".para << 
4550                     !strcmp(sec->name, ".retp << 
4551                     !strcmp(sec->name, ".smp_ << 
4552                     !strcmp(sec->name, ".stat << 
4553                     !strcmp(sec->name, "_erro << 
4554                     !strcmp(sec->name, "_kpro << 
4555                     !strcmp(sec->name, "__bug << 
4556                     !strcmp(sec->name, "__ex_ << 
4557                     !strcmp(sec->name, "__jum << 
4558                     !strcmp(sec->name, "__mco << 
4559                     !strcmp(sec->name, ".kcfi << 
4560                     strstr(sec->name, "__patc << 
4561                         continue;             << 
4562                                               << 
4563                 for_each_reloc(sec->rsec, rel << 
4564                         warnings += validate_ << 
4565         }                                     << 
4566                                               << 
4567         return warnings;                      << 
4568 }                                             << 
4569                                               << 
4570 static int validate_sls(struct objtool_file * << 
4571 {                                             << 
4572         struct instruction *insn, *next_insn; << 
4573         int warnings = 0;                     << 
4574                                               << 
4575         for_each_insn(file, insn) {           << 
4576                 next_insn = next_insn_same_se << 
4577                                               << 
4578                 if (insn->retpoline_safe)     << 
4579                         continue;             << 
4580                                               << 
4581                 switch (insn->type) {         << 
4582                 case INSN_RETURN:             << 
4583                         if (!next_insn || nex << 
4584                                 WARN_INSN(ins << 
4585                                 warnings++;   << 
4586                         }                     << 
4587                                                  2057 
4588                         break;                !! 2058                         ret = validate_branch(file, insn, state);
4589                 case INSN_JUMP_DYNAMIC:       !! 2059                         warnings += ret;
4590                         if (!next_insn || nex << 
4591                                 WARN_INSN(ins << 
4592                                 warnings++;   << 
4593                         }                     << 
4594                         break;                << 
4595                 default:                      << 
4596                         break;                << 
4597                 }                                2060                 }
4598         }                                        2061         }
4599                                                  2062 
4600         return warnings;                         2063         return warnings;
4601 }                                                2064 }
4602                                                  2065 
4603 static bool ignore_noreturn_call(struct instr << 
4604 {                                             << 
4605         struct symbol *call_dest = insn_call_ << 
4606                                               << 
4607         /*                                    << 
4608          * FIXME: hack, we need a real noretu << 
4609          *                                    << 
4610          * Problem is, exc_double_fault() may << 
4611          * whether CONFIG_X86_ESPFIX64 is set << 
4612          * to the kernel config.              << 
4613          *                                    << 
4614          * Other potential ways to fix it:    << 
4615          *                                    << 
4616          *   - have compiler communicate __no << 
4617          *   - remove CONFIG_X86_ESPFIX64     << 
4618          *   - read the .config file          << 
4619          *   - add a cmdline option           << 
4620          *   - create a generic objtool annot << 
4621          *     formats) and annotate it       << 
4622          */                                   << 
4623         if (!strcmp(call_dest->name, "exc_dou << 
4624                 /* prevent further unreachabl << 
4625                 insn->sym->warned = 1;        << 
4626                 return true;                  << 
4627         }                                     << 
4628                                               << 
4629         return false;                         << 
4630 }                                             << 
4631                                               << 
4632 static int validate_reachable_instructions(st    2066 static int validate_reachable_instructions(struct objtool_file *file)
4633 {                                                2067 {
4634         struct instruction *insn, *prev_insn; !! 2068         struct instruction *insn;
4635         struct symbol *call_dest;             << 
4636         int warnings = 0;                     << 
4637                                                  2069 
4638         if (file->ignore_unreachables)           2070         if (file->ignore_unreachables)
4639                 return 0;                        2071                 return 0;
4640                                                  2072 
4641         for_each_insn(file, insn) {              2073         for_each_insn(file, insn) {
4642                 if (insn->visited || ignore_u !! 2074                 if (insn->visited || ignore_unreachable_insn(insn))
4643                         continue;                2075                         continue;
4644                                                  2076 
4645                 prev_insn = prev_insn_same_se !! 2077                 WARN_FUNC("unreachable instruction", insn->sec, insn->offset);
4646                 if (prev_insn && prev_insn->d !! 2078                 return 1;
4647                         call_dest = insn_call << 
4648                         if (call_dest && !ign << 
4649                                 WARN_INSN(ins << 
4650                                           cal << 
4651                                 warnings++;   << 
4652                                 continue;     << 
4653                         }                     << 
4654                 }                             << 
4655                                               << 
4656                 WARN_INSN(insn, "unreachable  << 
4657                 warnings++;                   << 
4658         }                                     << 
4659                                               << 
4660         return warnings;                      << 
4661 }                                             << 
4662                                               << 
4663 /* 'funcs' is a space-separated list of funct << 
4664 static int disas_funcs(const char *funcs)     << 
4665 {                                             << 
4666         const char *objdump_str, *cross_compi << 
4667         int size, ret;                        << 
4668         char *cmd;                            << 
4669                                               << 
4670         cross_compile = getenv("CROSS_COMPILE << 
4671                                               << 
4672         objdump_str = "%sobjdump -wdr %s | ga << 
4673                         "BEGIN { split(_funcs << 
4674                         "/^$/ { func_match =  << 
4675                         "/<.*>:/ { "          << 
4676                                 "f = gensub(/ << 
4677                                 "for (i in fu << 
4678                                         "if ( << 
4679                                               << 
4680                                               << 
4681                                               << 
4682                                         "}"   << 
4683                                 "}"           << 
4684                         "}"                   << 
4685                         "{"                   << 
4686                                 "if (func_mat << 
4687                                         "addr << 
4688                                         "prin << 
4689                                         "prin << 
4690                                 "}"           << 
4691                         "}' 1>&2";            << 
4692                                               << 
4693         /* fake snprintf() to calculate the s << 
4694         size = snprintf(NULL, 0, objdump_str, << 
4695         if (size <= 0) {                      << 
4696                 WARN("objdump string size cal << 
4697                 return -1;                    << 
4698         }                                     << 
4699                                               << 
4700         cmd = malloc(size);                   << 
4701                                               << 
4702         /* real snprintf() */                 << 
4703         snprintf(cmd, size, objdump_str, cros << 
4704         ret = system(cmd);                    << 
4705         if (ret) {                            << 
4706                 WARN("disassembly failed: %d" << 
4707                 return -1;                    << 
4708         }                                        2079         }
4709                                                  2080 
4710         return 0;                                2081         return 0;
4711 }                                                2082 }
4712                                                  2083 
4713 static int disas_warned_funcs(struct objtool_ !! 2084 static void cleanup(struct objtool_file *file)
4714 {                                                2085 {
4715         struct symbol *sym;                   !! 2086         struct instruction *insn, *tmpinsn;
4716         char *funcs = NULL, *tmp;             !! 2087         struct alternative *alt, *tmpalt;
4717                                                  2088 
4718         for_each_sym(file, sym) {             !! 2089         list_for_each_entry_safe(insn, tmpinsn, &file->insn_list, list) {
4719                 if (sym->warned) {            !! 2090                 list_for_each_entry_safe(alt, tmpalt, &insn->alts, list) {
4720                         if (!funcs) {         !! 2091                         list_del(&alt->list);
4721                                 funcs = mallo !! 2092                         free(alt);
4722                                 strcpy(funcs, << 
4723                         } else {              << 
4724                                 tmp = malloc( << 
4725                                 sprintf(tmp,  << 
4726                                 free(funcs);  << 
4727                                 funcs = tmp;  << 
4728                         }                     << 
4729                 }                                2093                 }
                                                   >> 2094                 list_del(&insn->list);
                                                   >> 2095                 hash_del(&insn->hash);
                                                   >> 2096                 free(insn);
4730         }                                        2097         }
4731                                               !! 2098         elf_close(file->elf);
4732         if (funcs)                            << 
4733                 disas_funcs(funcs);           << 
4734                                               << 
4735         return 0;                             << 
4736 }                                                2099 }
4737                                                  2100 
4738 struct insn_chunk {                           !! 2101 int check(const char *_objname, bool orc)
4739         void *addr;                           << 
4740         struct insn_chunk *next;              << 
4741 };                                            << 
4742                                               << 
4743 /*                                            << 
4744  * Reduce peak RSS usage by freeing insns mem << 
4745  * which can trigger more allocations for .de << 
4746  * been read yet.                             << 
4747  */                                           << 
4748 static void free_insns(struct objtool_file *f << 
4749 {                                                2102 {
4750         struct instruction *insn;             !! 2103         struct objtool_file file;
4751         struct insn_chunk *chunks = NULL, *ch !! 2104         int ret, warnings = 0;
4752                                                  2105 
4753         for_each_insn(file, insn) {           !! 2106         objname = _objname;
4754                 if (!insn->idx) {             << 
4755                         chunk = malloc(sizeof << 
4756                         chunk->addr = insn;   << 
4757                         chunk->next = chunks; << 
4758                         chunks = chunk;       << 
4759                 }                             << 
4760         }                                     << 
4761                                                  2107 
4762         for (chunk = chunks; chunk; chunk = c !! 2108         file.elf = elf_open(objname, orc ? O_RDWR : O_RDONLY);
4763                 free(chunk->addr);            !! 2109         if (!file.elf)
4764 }                                             !! 2110                 return 1;
4765                                                  2111 
4766 int check(struct objtool_file *file)          !! 2112         INIT_LIST_HEAD(&file.insn_list);
4767 {                                             !! 2113         hash_init(file.insn_hash);
4768         int ret, warnings = 0;                !! 2114         file.whitelist = find_section_by_name(file.elf, ".discard.func_stack_frame_non_standard");
                                                   >> 2115         file.rodata = find_section_by_name(file.elf, ".rodata");
                                                   >> 2116         file.c_file = find_section_by_name(file.elf, ".comment");
                                                   >> 2117         file.ignore_unreachables = no_unreachable;
                                                   >> 2118         file.hints = false;
4769                                                  2119 
4770         arch_initial_func_cfi_state(&initial_    2120         arch_initial_func_cfi_state(&initial_func_cfi);
4771         init_cfi_state(&init_cfi);            << 
4772         init_cfi_state(&func_cfi);            << 
4773         set_func_state(&func_cfi);            << 
4774         init_cfi_state(&force_undefined_cfi); << 
4775         force_undefined_cfi.force_undefined = << 
4776                                               << 
4777         if (!cfi_hash_alloc(1UL << (file->elf << 
4778                 goto out;                     << 
4779                                                  2121 
4780         cfi_hash_add(&init_cfi);              !! 2122         ret = decode_sections(&file);
4781         cfi_hash_add(&func_cfi);              << 
4782                                               << 
4783         ret = decode_sections(file);          << 
4784         if (ret < 0)                             2123         if (ret < 0)
4785                 goto out;                        2124                 goto out;
4786                                               << 
4787         warnings += ret;                         2125         warnings += ret;
4788                                                  2126 
4789         if (!nr_insns)                        !! 2127         if (list_empty(&file.insn_list))
4790                 goto out;                        2128                 goto out;
4791                                                  2129 
4792         if (opts.retpoline) {                 !! 2130         if (retpoline) {
4793                 ret = validate_retpoline(file !! 2131                 ret = validate_retpoline(&file);
4794                 if (ret < 0)                  << 
4795                         return ret;           << 
4796                 warnings += ret;              << 
4797         }                                     << 
4798                                               << 
4799         if (opts.stackval || opts.orc || opts << 
4800                 ret = validate_functions(file << 
4801                 if (ret < 0)                  << 
4802                         goto out;             << 
4803                 warnings += ret;              << 
4804                                               << 
4805                 ret = validate_unwind_hints(f << 
4806                 if (ret < 0)                  << 
4807                         goto out;             << 
4808                 warnings += ret;              << 
4809                                               << 
4810                 if (!warnings) {              << 
4811                         ret = validate_reacha << 
4812                         if (ret < 0)          << 
4813                                 goto out;     << 
4814                         warnings += ret;      << 
4815                 }                             << 
4816                                               << 
4817         } else if (opts.noinstr) {            << 
4818                 ret = validate_noinstr_sectio << 
4819                 if (ret < 0)                  << 
4820                         goto out;             << 
4821                 warnings += ret;              << 
4822         }                                     << 
4823                                               << 
4824         if (opts.unret) {                     << 
4825                 /*                            << 
4826                  * Must be after validate_bra << 
4827                  * further games with insn->v << 
4828                  */                           << 
4829                 ret = validate_unrets(file);  << 
4830                 if (ret < 0)                     2132                 if (ret < 0)
4831                         return ret;              2133                         return ret;
4832                 warnings += ret;                 2134                 warnings += ret;
4833         }                                        2135         }
4834                                                  2136 
4835         if (opts.ibt) {                       !! 2137         ret = validate_functions(&file);
4836                 ret = validate_ibt(file);     !! 2138         if (ret < 0)
4837                 if (ret < 0)                  !! 2139                 goto out;
4838                         goto out;             !! 2140         warnings += ret;
4839                 warnings += ret;              << 
4840         }                                     << 
4841                                               << 
4842         if (opts.sls) {                       << 
4843                 ret = validate_sls(file);     << 
4844                 if (ret < 0)                  << 
4845                         goto out;             << 
4846                 warnings += ret;              << 
4847         }                                     << 
4848                                               << 
4849         if (opts.static_call) {               << 
4850                 ret = create_static_call_sect << 
4851                 if (ret < 0)                  << 
4852                         goto out;             << 
4853                 warnings += ret;              << 
4854         }                                     << 
4855                                               << 
4856         if (opts.retpoline) {                 << 
4857                 ret = create_retpoline_sites_ << 
4858                 if (ret < 0)                  << 
4859                         goto out;             << 
4860                 warnings += ret;              << 
4861         }                                     << 
4862                                                  2141 
4863         if (opts.cfi) {                       !! 2142         ret = validate_unwind_hints(&file);
4864                 ret = create_cfi_sections(fil !! 2143         if (ret < 0)
4865                 if (ret < 0)                  !! 2144                 goto out;
4866                         goto out;             !! 2145         warnings += ret;
4867                 warnings += ret;              << 
4868         }                                     << 
4869                                                  2146 
4870         if (opts.rethunk) {                   !! 2147         if (!warnings) {
4871                 ret = create_return_sites_sec !! 2148                 ret = validate_reachable_instructions(&file);
4872                 if (ret < 0)                     2149                 if (ret < 0)
4873                         goto out;                2150                         goto out;
4874                 warnings += ret;                 2151                 warnings += ret;
4875                                               << 
4876                 if (opts.hack_skylake) {      << 
4877                         ret = create_direct_c << 
4878                         if (ret < 0)          << 
4879                                 goto out;     << 
4880                         warnings += ret;      << 
4881                 }                             << 
4882         }                                        2152         }
4883                                                  2153 
4884         if (opts.mcount) {                    !! 2154         if (orc) {
4885                 ret = create_mcount_loc_secti !! 2155                 ret = create_orc(&file);
4886                 if (ret < 0)                     2156                 if (ret < 0)
4887                         goto out;                2157                         goto out;
4888                 warnings += ret;              << 
4889         }                                     << 
4890                                                  2158 
4891         if (opts.prefix) {                    !! 2159                 ret = create_orc_sections(&file);
4892                 ret = add_prefix_symbols(file << 
4893                 if (ret < 0)                  << 
4894                         return ret;           << 
4895                 warnings += ret;              << 
4896         }                                     << 
4897                                               << 
4898         if (opts.ibt) {                       << 
4899                 ret = create_ibt_endbr_seal_s << 
4900                 if (ret < 0)                     2160                 if (ret < 0)
4901                         goto out;                2161                         goto out;
4902                 warnings += ret;              << 
4903         }                                     << 
4904                                                  2162 
4905         if (opts.orc && nr_insns) {           !! 2163                 ret = elf_write(file.elf);
4906                 ret = orc_create(file);       << 
4907                 if (ret < 0)                     2164                 if (ret < 0)
4908                         goto out;                2165                         goto out;
4909                 warnings += ret;              << 
4910         }                                     << 
4911                                               << 
4912         free_insns(file);                     << 
4913                                               << 
4914         if (opts.verbose)                     << 
4915                 disas_warned_funcs(file);     << 
4916                                               << 
4917         if (opts.stats) {                     << 
4918                 printf("nr_insns_visited: %ld << 
4919                 printf("nr_cfi: %ld\n", nr_cf << 
4920                 printf("nr_cfi_reused: %ld\n" << 
4921                 printf("nr_cfi_cache: %ld\n", << 
4922         }                                        2166         }
4923                                                  2167 
4924 out:                                             2168 out:
4925         /*                                    !! 2169         cleanup(&file);
4926          *  For now, don't fail the kernel bu !! 2170 
4927          *  errors are still fairly common du !! 2171         /* ignore warnings for now until we get all the code cleaned up */
4928          *  supported toolchains and their re !! 2172         if (ret || warnings)
4929          */                                   !! 2173                 return 0;
4930         return 0;                                2174         return 0;
4931 }                                                2175 }
4932                                                  2176 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php