linux/tools/objtool/builtin-check.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2015 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/>.
  16 */
  17
  18/*
  19 * objtool check:
  20 *
  21 * This command analyzes every .o file and ensures the validity of its stack
  22 * trace metadata.  It enforces a set of rules on asm code and C inline
  23 * assembly code so that stack traces can be reliable.
  24 *
  25 * For more information, see tools/objtool/Documentation/stack-validation.txt.
  26 */
  27
  28#include <string.h>
  29#include <stdlib.h>
  30#include <subcmd/parse-options.h>
  31
  32#include "builtin.h"
  33#include "elf.h"
  34#include "special.h"
  35#include "arch.h"
  36#include "warn.h"
  37
  38#include <linux/hashtable.h>
  39
  40#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
  41
  42#define STATE_FP_SAVED          0x1
  43#define STATE_FP_SETUP          0x2
  44#define STATE_FENTRY            0x4
  45
  46struct instruction {
  47        struct list_head list;
  48        struct hlist_node hash;
  49        struct section *sec;
  50        unsigned long offset;
  51        unsigned int len, state;
  52        unsigned char type;
  53        unsigned long immediate;
  54        bool alt_group, visited;
  55        struct symbol *call_dest;
  56        struct instruction *jump_dest;
  57        struct list_head alts;
  58        struct symbol *func;
  59};
  60
  61struct alternative {
  62        struct list_head list;
  63        struct instruction *insn;
  64};
  65
  66struct objtool_file {
  67        struct elf *elf;
  68        struct list_head insn_list;
  69        DECLARE_HASHTABLE(insn_hash, 16);
  70        struct section *rodata, *whitelist;
  71        bool ignore_unreachables, c_file;
  72};
  73
  74const char *objname;
  75static bool nofp;
  76
  77static struct instruction *find_insn(struct objtool_file *file,
  78                                     struct section *sec, unsigned long offset)
  79{
  80        struct instruction *insn;
  81
  82        hash_for_each_possible(file->insn_hash, insn, hash, offset)
  83                if (insn->sec == sec && insn->offset == offset)
  84                        return insn;
  85
  86        return NULL;
  87}
  88
  89static struct instruction *next_insn_same_sec(struct objtool_file *file,
  90                                              struct instruction *insn)
  91{
  92        struct instruction *next = list_next_entry(insn, list);
  93
  94        if (&next->list == &file->insn_list || next->sec != insn->sec)
  95                return NULL;
  96
  97        return next;
  98}
  99
 100#define for_each_insn(file, insn)                                       \
 101        list_for_each_entry(insn, &file->insn_list, list)
 102
 103#define func_for_each_insn(file, func, insn)                            \
 104        for (insn = find_insn(file, func->sec, func->offset);           \
 105             insn && &insn->list != &file->insn_list &&                 \
 106                insn->sec == func->sec &&                               \
 107                insn->offset < func->offset + func->len;                \
 108             insn = list_next_entry(insn, list))
 109
 110#define func_for_each_insn_continue_reverse(file, func, insn)           \
 111        for (insn = list_prev_entry(insn, list);                        \
 112             &insn->list != &file->insn_list &&                         \
 113                insn->sec == func->sec && insn->offset >= func->offset; \
 114             insn = list_prev_entry(insn, list))
 115
 116#define sec_for_each_insn_from(file, insn)                              \
 117        for (; insn; insn = next_insn_same_sec(file, insn))
 118
 119
 120/*
 121 * Check if the function has been manually whitelisted with the
 122 * STACK_FRAME_NON_STANDARD macro, or if it should be automatically whitelisted
 123 * due to its use of a context switching instruction.
 124 */
 125static bool ignore_func(struct objtool_file *file, struct symbol *func)
 126{
 127        struct rela *rela;
 128        struct instruction *insn;
 129
 130        /* check for STACK_FRAME_NON_STANDARD */
 131        if (file->whitelist && file->whitelist->rela)
 132                list_for_each_entry(rela, &file->whitelist->rela->rela_list, list) {
 133                        if (rela->sym->type == STT_SECTION &&
 134                            rela->sym->sec == func->sec &&
 135                            rela->addend == func->offset)
 136                                return true;
 137                        if (rela->sym->type == STT_FUNC && rela->sym == func)
 138                                return true;
 139                }
 140
 141        /* check if it has a context switching instruction */
 142        func_for_each_insn(file, func, insn)
 143                if (insn->type == INSN_CONTEXT_SWITCH)
 144                        return true;
 145
 146        return false;
 147}
 148
 149/*
 150 * This checks to see if the given function is a "noreturn" function.
 151 *
 152 * For global functions which are outside the scope of this object file, we
 153 * have to keep a manual list of them.
 154 *
 155 * For local functions, we have to detect them manually by simply looking for
 156 * the lack of a return instruction.
 157 *
 158 * Returns:
 159 *  -1: error
 160 *   0: no dead end
 161 *   1: dead end
 162 */
 163static int __dead_end_function(struct objtool_file *file, struct symbol *func,
 164                               int recursion)
 165{
 166        int i;
 167        struct instruction *insn;
 168        bool empty = true;
 169
 170        /*
 171         * Unfortunately these have to be hard coded because the noreturn
 172         * attribute isn't provided in ELF data.
 173         */
 174        static const char * const global_noreturns[] = {
 175                "__stack_chk_fail",
 176                "panic",
 177                "do_exit",
 178                "__module_put_and_exit",
 179                "complete_and_exit",
 180                "kvm_spurious_fault",
 181                "__reiserfs_panic",
 182                "lbug_with_loc"
 183        };
 184
 185        if (func->bind == STB_WEAK)
 186                return 0;
 187
 188        if (func->bind == STB_GLOBAL)
 189                for (i = 0; i < ARRAY_SIZE(global_noreturns); i++)
 190                        if (!strcmp(func->name, global_noreturns[i]))
 191                                return 1;
 192
 193        if (!func->sec)
 194                return 0;
 195
 196        func_for_each_insn(file, func, insn) {
 197                empty = false;
 198
 199                if (insn->type == INSN_RETURN)
 200                        return 0;
 201        }
 202
 203        if (empty)
 204                return 0;
 205
 206        /*
 207         * A function can have a sibling call instead of a return.  In that
 208         * case, the function's dead-end status depends on whether the target
 209         * of the sibling call returns.
 210         */
 211        func_for_each_insn(file, func, insn) {
 212                if (insn->sec != func->sec ||
 213                    insn->offset >= func->offset + func->len)
 214                        break;
 215
 216                if (insn->type == INSN_JUMP_UNCONDITIONAL) {
 217                        struct instruction *dest = insn->jump_dest;
 218                        struct symbol *dest_func;
 219
 220                        if (!dest)
 221                                /* sibling call to another file */
 222                                return 0;
 223
 224                        if (dest->sec != func->sec ||
 225                            dest->offset < func->offset ||
 226                            dest->offset >= func->offset + func->len) {
 227                                /* local sibling call */
 228                                dest_func = find_symbol_by_offset(dest->sec,
 229                                                                  dest->offset);
 230                                if (!dest_func)
 231                                        continue;
 232
 233                                if (recursion == 5) {
 234                                        WARN_FUNC("infinite recursion (objtool bug!)",
 235                                                  dest->sec, dest->offset);
 236                                        return -1;
 237                                }
 238
 239                                return __dead_end_function(file, dest_func,
 240                                                           recursion + 1);
 241                        }
 242                }
 243
 244                if (insn->type == INSN_JUMP_DYNAMIC && list_empty(&insn->alts))
 245                        /* sibling call */
 246                        return 0;
 247        }
 248
 249        return 1;
 250}
 251
 252static int dead_end_function(struct objtool_file *file, struct symbol *func)
 253{
 254        return __dead_end_function(file, func, 0);
 255}
 256
 257/*
 258 * Call the arch-specific instruction decoder for all the instructions and add
 259 * them to the global instruction list.
 260 */
 261static int decode_instructions(struct objtool_file *file)
 262{
 263        struct section *sec;
 264        struct symbol *func;
 265        unsigned long offset;
 266        struct instruction *insn;
 267        int ret;
 268
 269        list_for_each_entry(sec, &file->elf->sections, list) {
 270
 271                if (!(sec->sh.sh_flags & SHF_EXECINSTR))
 272                        continue;
 273
 274                for (offset = 0; offset < sec->len; offset += insn->len) {
 275                        insn = malloc(sizeof(*insn));
 276                        memset(insn, 0, sizeof(*insn));
 277
 278                        INIT_LIST_HEAD(&insn->alts);
 279                        insn->sec = sec;
 280                        insn->offset = offset;
 281
 282                        ret = arch_decode_instruction(file->elf, sec, offset,
 283                                                      sec->len - offset,
 284                                                      &insn->len, &insn->type,
 285                                                      &insn->immediate);
 286                        if (ret)
 287                                return ret;
 288
 289                        if (!insn->type || insn->type > INSN_LAST) {
 290                                WARN_FUNC("invalid instruction type %d",
 291                                          insn->sec, insn->offset, insn->type);
 292                                return -1;
 293                        }
 294
 295                        hash_add(file->insn_hash, &insn->hash, insn->offset);
 296                        list_add_tail(&insn->list, &file->insn_list);
 297                }
 298
 299                list_for_each_entry(func, &sec->symbol_list, list) {
 300                        if (func->type != STT_FUNC)
 301                                continue;
 302
 303                        if (!find_insn(file, sec, func->offset)) {
 304                                WARN("%s(): can't find starting instruction",
 305                                     func->name);
 306                                return -1;
 307                        }
 308
 309                        func_for_each_insn(file, func, insn)
 310                                if (!insn->func)
 311                                        insn->func = func;
 312                }
 313        }
 314
 315        return 0;
 316}
 317
 318/*
 319 * Warnings shouldn't be reported for ignored functions.
 320 */
 321static void add_ignores(struct objtool_file *file)
 322{
 323        struct instruction *insn;
 324        struct section *sec;
 325        struct symbol *func;
 326
 327        list_for_each_entry(sec, &file->elf->sections, list) {
 328                list_for_each_entry(func, &sec->symbol_list, list) {
 329                        if (func->type != STT_FUNC)
 330                                continue;
 331
 332                        if (!ignore_func(file, func))
 333                                continue;
 334
 335                        func_for_each_insn(file, func, insn)
 336                                insn->visited = true;
 337                }
 338        }
 339}
 340
 341/*
 342 * Find the destination instructions for all jumps.
 343 */
 344static int add_jump_destinations(struct objtool_file *file)
 345{
 346        struct instruction *insn;
 347        struct rela *rela;
 348        struct section *dest_sec;
 349        unsigned long dest_off;
 350
 351        for_each_insn(file, insn) {
 352                if (insn->type != INSN_JUMP_CONDITIONAL &&
 353                    insn->type != INSN_JUMP_UNCONDITIONAL)
 354                        continue;
 355
 356                /* skip ignores */
 357                if (insn->visited)
 358                        continue;
 359
 360                rela = find_rela_by_dest_range(insn->sec, insn->offset,
 361                                               insn->len);
 362                if (!rela) {
 363                        dest_sec = insn->sec;
 364                        dest_off = insn->offset + insn->len + insn->immediate;
 365                } else if (rela->sym->type == STT_SECTION) {
 366                        dest_sec = rela->sym->sec;
 367                        dest_off = rela->addend + 4;
 368                } else if (rela->sym->sec->idx) {
 369                        dest_sec = rela->sym->sec;
 370                        dest_off = rela->sym->sym.st_value + rela->addend + 4;
 371                } else {
 372                        /* sibling call */
 373                        insn->jump_dest = 0;
 374                        continue;
 375                }
 376
 377                insn->jump_dest = find_insn(file, dest_sec, dest_off);
 378                if (!insn->jump_dest) {
 379
 380                        /*
 381                         * This is a special case where an alt instruction
 382                         * jumps past the end of the section.  These are
 383                         * handled later in handle_group_alt().
 384                         */
 385                        if (!strcmp(insn->sec->name, ".altinstr_replacement"))
 386                                continue;
 387
 388                        WARN_FUNC("can't find jump dest instruction at %s+0x%lx",
 389                                  insn->sec, insn->offset, dest_sec->name,
 390                                  dest_off);
 391                        return -1;
 392                }
 393        }
 394
 395        return 0;
 396}
 397
 398/*
 399 * Find the destination instructions for all calls.
 400 */
 401static int add_call_destinations(struct objtool_file *file)
 402{
 403        struct instruction *insn;
 404        unsigned long dest_off;
 405        struct rela *rela;
 406
 407        for_each_insn(file, insn) {
 408                if (insn->type != INSN_CALL)
 409                        continue;
 410
 411                rela = find_rela_by_dest_range(insn->sec, insn->offset,
 412                                               insn->len);
 413                if (!rela) {
 414                        dest_off = insn->offset + insn->len + insn->immediate;
 415                        insn->call_dest = find_symbol_by_offset(insn->sec,
 416                                                                dest_off);
 417                        if (!insn->call_dest) {
 418                                WARN_FUNC("can't find call dest symbol at offset 0x%lx",
 419                                          insn->sec, insn->offset, dest_off);
 420                                return -1;
 421                        }
 422                } else if (rela->sym->type == STT_SECTION) {
 423                        insn->call_dest = find_symbol_by_offset(rela->sym->sec,
 424                                                                rela->addend+4);
 425                        if (!insn->call_dest ||
 426                            insn->call_dest->type != STT_FUNC) {
 427                                WARN_FUNC("can't find call dest symbol at %s+0x%x",
 428                                          insn->sec, insn->offset,
 429                                          rela->sym->sec->name,
 430                                          rela->addend + 4);
 431                                return -1;
 432                        }
 433                } else
 434                        insn->call_dest = rela->sym;
 435        }
 436
 437        return 0;
 438}
 439
 440/*
 441 * The .alternatives section requires some extra special care, over and above
 442 * what other special sections require:
 443 *
 444 * 1. Because alternatives are patched in-place, we need to insert a fake jump
 445 *    instruction at the end so that validate_branch() skips all the original
 446 *    replaced instructions when validating the new instruction path.
 447 *
 448 * 2. An added wrinkle is that the new instruction length might be zero.  In
 449 *    that case the old instructions are replaced with noops.  We simulate that
 450 *    by creating a fake jump as the only new instruction.
 451 *
 452 * 3. In some cases, the alternative section includes an instruction which
 453 *    conditionally jumps to the _end_ of the entry.  We have to modify these
 454 *    jumps' destinations to point back to .text rather than the end of the
 455 *    entry in .altinstr_replacement.
 456 *
 457 * 4. It has been requested that we don't validate the !POPCNT feature path
 458 *    which is a "very very small percentage of machines".
 459 */
 460static int handle_group_alt(struct objtool_file *file,
 461                            struct special_alt *special_alt,
 462                            struct instruction *orig_insn,
 463                            struct instruction **new_insn)
 464{
 465        struct instruction *last_orig_insn, *last_new_insn, *insn, *fake_jump;
 466        unsigned long dest_off;
 467
 468        last_orig_insn = NULL;
 469        insn = orig_insn;
 470        sec_for_each_insn_from(file, insn) {
 471                if (insn->offset >= special_alt->orig_off + special_alt->orig_len)
 472                        break;
 473
 474                if (special_alt->skip_orig)
 475                        insn->type = INSN_NOP;
 476
 477                insn->alt_group = true;
 478                last_orig_insn = insn;
 479        }
 480
 481        if (!next_insn_same_sec(file, last_orig_insn)) {
 482                WARN("%s: don't know how to handle alternatives at end of section",
 483                     special_alt->orig_sec->name);
 484                return -1;
 485        }
 486
 487        fake_jump = malloc(sizeof(*fake_jump));
 488        if (!fake_jump) {
 489                WARN("malloc failed");
 490                return -1;
 491        }
 492        memset(fake_jump, 0, sizeof(*fake_jump));
 493        INIT_LIST_HEAD(&fake_jump->alts);
 494        fake_jump->sec = special_alt->new_sec;
 495        fake_jump->offset = -1;
 496        fake_jump->type = INSN_JUMP_UNCONDITIONAL;
 497        fake_jump->jump_dest = list_next_entry(last_orig_insn, list);
 498
 499        if (!special_alt->new_len) {
 500                *new_insn = fake_jump;
 501                return 0;
 502        }
 503
 504        last_new_insn = NULL;
 505        insn = *new_insn;
 506        sec_for_each_insn_from(file, insn) {
 507                if (insn->offset >= special_alt->new_off + special_alt->new_len)
 508                        break;
 509
 510                last_new_insn = insn;
 511
 512                if (insn->type != INSN_JUMP_CONDITIONAL &&
 513                    insn->type != INSN_JUMP_UNCONDITIONAL)
 514                        continue;
 515
 516                if (!insn->immediate)
 517                        continue;
 518
 519                dest_off = insn->offset + insn->len + insn->immediate;
 520                if (dest_off == special_alt->new_off + special_alt->new_len)
 521                        insn->jump_dest = fake_jump;
 522
 523                if (!insn->jump_dest) {
 524                        WARN_FUNC("can't find alternative jump destination",
 525                                  insn->sec, insn->offset);
 526                        return -1;
 527                }
 528        }
 529
 530        if (!last_new_insn) {
 531                WARN_FUNC("can't find last new alternative instruction",
 532                          special_alt->new_sec, special_alt->new_off);
 533                return -1;
 534        }
 535
 536        list_add(&fake_jump->list, &last_new_insn->list);
 537
 538        return 0;
 539}
 540
 541/*
 542 * A jump table entry can either convert a nop to a jump or a jump to a nop.
 543 * If the original instruction is a jump, make the alt entry an effective nop
 544 * by just skipping the original instruction.
 545 */
 546static int handle_jump_alt(struct objtool_file *file,
 547                           struct special_alt *special_alt,
 548                           struct instruction *orig_insn,
 549                           struct instruction **new_insn)
 550{
 551        if (orig_insn->type == INSN_NOP)
 552                return 0;
 553
 554        if (orig_insn->type != INSN_JUMP_UNCONDITIONAL) {
 555                WARN_FUNC("unsupported instruction at jump label",
 556                          orig_insn->sec, orig_insn->offset);
 557                return -1;
 558        }
 559
 560        *new_insn = list_next_entry(orig_insn, list);
 561        return 0;
 562}
 563
 564/*
 565 * Read all the special sections which have alternate instructions which can be
 566 * patched in or redirected to at runtime.  Each instruction having alternate
 567 * instruction(s) has them added to its insn->alts list, which will be
 568 * traversed in validate_branch().
 569 */
 570static int add_special_section_alts(struct objtool_file *file)
 571{
 572        struct list_head special_alts;
 573        struct instruction *orig_insn, *new_insn;
 574        struct special_alt *special_alt, *tmp;
 575        struct alternative *alt;
 576        int ret;
 577
 578        ret = special_get_alts(file->elf, &special_alts);
 579        if (ret)
 580                return ret;
 581
 582        list_for_each_entry_safe(special_alt, tmp, &special_alts, list) {
 583                alt = malloc(sizeof(*alt));
 584                if (!alt) {
 585                        WARN("malloc failed");
 586                        ret = -1;
 587                        goto out;
 588                }
 589
 590                orig_insn = find_insn(file, special_alt->orig_sec,
 591                                      special_alt->orig_off);
 592                if (!orig_insn) {
 593                        WARN_FUNC("special: can't find orig instruction",
 594                                  special_alt->orig_sec, special_alt->orig_off);
 595                        ret = -1;
 596                        goto out;
 597                }
 598
 599                new_insn = NULL;
 600                if (!special_alt->group || special_alt->new_len) {
 601                        new_insn = find_insn(file, special_alt->new_sec,
 602                                             special_alt->new_off);
 603                        if (!new_insn) {
 604                                WARN_FUNC("special: can't find new instruction",
 605                                          special_alt->new_sec,
 606                                          special_alt->new_off);
 607                                ret = -1;
 608                                goto out;
 609                        }
 610                }
 611
 612                if (special_alt->group) {
 613                        ret = handle_group_alt(file, special_alt, orig_insn,
 614                                               &new_insn);
 615                        if (ret)
 616                                goto out;
 617                } else if (special_alt->jump_or_nop) {
 618                        ret = handle_jump_alt(file, special_alt, orig_insn,
 619                                              &new_insn);
 620                        if (ret)
 621                                goto out;
 622                }
 623
 624                alt->insn = new_insn;
 625                list_add_tail(&alt->list, &orig_insn->alts);
 626
 627                list_del(&special_alt->list);
 628                free(special_alt);
 629        }
 630
 631out:
 632        return ret;
 633}
 634
 635static int add_switch_table(struct objtool_file *file, struct symbol *func,
 636                            struct instruction *insn, struct rela *table,
 637                            struct rela *next_table)
 638{
 639        struct rela *rela = table;
 640        struct instruction *alt_insn;
 641        struct alternative *alt;
 642
 643        list_for_each_entry_from(rela, &file->rodata->rela->rela_list, list) {
 644                if (rela == next_table)
 645                        break;
 646
 647                if (rela->sym->sec != insn->sec ||
 648                    rela->addend <= func->offset ||
 649                    rela->addend >= func->offset + func->len)
 650                        break;
 651
 652                alt_insn = find_insn(file, insn->sec, rela->addend);
 653                if (!alt_insn) {
 654                        WARN("%s: can't find instruction at %s+0x%x",
 655                             file->rodata->rela->name, insn->sec->name,
 656                             rela->addend);
 657                        return -1;
 658                }
 659
 660                alt = malloc(sizeof(*alt));
 661                if (!alt) {
 662                        WARN("malloc failed");
 663                        return -1;
 664                }
 665
 666                alt->insn = alt_insn;
 667                list_add_tail(&alt->list, &insn->alts);
 668        }
 669
 670        return 0;
 671}
 672
 673/*
 674 * find_switch_table() - Given a dynamic jump, find the switch jump table in
 675 * .rodata associated with it.
 676 *
 677 * There are 3 basic patterns:
 678 *
 679 * 1. jmpq *[rodata addr](,%reg,8)
 680 *
 681 *    This is the most common case by far.  It jumps to an address in a simple
 682 *    jump table which is stored in .rodata.
 683 *
 684 * 2. jmpq *[rodata addr](%rip)
 685 *
 686 *    This is caused by a rare GCC quirk, currently only seen in three driver
 687 *    functions in the kernel, only with certain obscure non-distro configs.
 688 *
 689 *    As part of an optimization, GCC makes a copy of an existing switch jump
 690 *    table, modifies it, and then hard-codes the jump (albeit with an indirect
 691 *    jump) to use a single entry in the table.  The rest of the jump table and
 692 *    some of its jump targets remain as dead code.
 693 *
 694 *    In such a case we can just crudely ignore all unreachable instruction
 695 *    warnings for the entire object file.  Ideally we would just ignore them
 696 *    for the function, but that would require redesigning the code quite a
 697 *    bit.  And honestly that's just not worth doing: unreachable instruction
 698 *    warnings are of questionable value anyway, and this is such a rare issue.
 699 *
 700 * 3. mov [rodata addr],%reg1
 701 *    ... some instructions ...
 702 *    jmpq *(%reg1,%reg2,8)
 703 *
 704 *    This is a fairly uncommon pattern which is new for GCC 6.  As of this
 705 *    writing, there are 11 occurrences of it in the allmodconfig kernel.
 706 *
 707 *    TODO: Once we have DWARF CFI and smarter instruction decoding logic,
 708 *    ensure the same register is used in the mov and jump instructions.
 709 */
 710static struct rela *find_switch_table(struct objtool_file *file,
 711                                      struct symbol *func,
 712                                      struct instruction *insn)
 713{
 714        struct rela *text_rela, *rodata_rela;
 715
 716        text_rela = find_rela_by_dest_range(insn->sec, insn->offset, insn->len);
 717        if (text_rela && text_rela->sym == file->rodata->sym) {
 718                /* case 1 */
 719                rodata_rela = find_rela_by_dest(file->rodata,
 720                                                text_rela->addend);
 721                if (rodata_rela)
 722                        return rodata_rela;
 723
 724                /* case 2 */
 725                rodata_rela = find_rela_by_dest(file->rodata,
 726                                                text_rela->addend + 4);
 727                if (!rodata_rela)
 728                        return NULL;
 729                file->ignore_unreachables = true;
 730                return rodata_rela;
 731        }
 732
 733        /* case 3 */
 734        func_for_each_insn_continue_reverse(file, func, insn) {
 735                if (insn->type == INSN_JUMP_UNCONDITIONAL ||
 736                    insn->type == INSN_JUMP_DYNAMIC)
 737                        break;
 738
 739                text_rela = find_rela_by_dest_range(insn->sec, insn->offset,
 740                                                    insn->len);
 741                if (text_rela && text_rela->sym == file->rodata->sym)
 742                        return find_rela_by_dest(file->rodata,
 743                                                 text_rela->addend);
 744        }
 745
 746        return NULL;
 747}
 748
 749static int add_func_switch_tables(struct objtool_file *file,
 750                                  struct symbol *func)
 751{
 752        struct instruction *insn, *prev_jump = NULL;
 753        struct rela *rela, *prev_rela = NULL;
 754        int ret;
 755
 756        func_for_each_insn(file, func, insn) {
 757                if (insn->type != INSN_JUMP_DYNAMIC)
 758                        continue;
 759
 760                rela = find_switch_table(file, func, insn);
 761                if (!rela)
 762                        continue;
 763
 764                /*
 765                 * We found a switch table, but we don't know yet how big it
 766                 * is.  Don't add it until we reach the end of the function or
 767                 * the beginning of another switch table in the same function.
 768                 */
 769                if (prev_jump) {
 770                        ret = add_switch_table(file, func, prev_jump, prev_rela,
 771                                               rela);
 772                        if (ret)
 773                                return ret;
 774                }
 775
 776                prev_jump = insn;
 777                prev_rela = rela;
 778        }
 779
 780        if (prev_jump) {
 781                ret = add_switch_table(file, func, prev_jump, prev_rela, NULL);
 782                if (ret)
 783                        return ret;
 784        }
 785
 786        return 0;
 787}
 788
 789/*
 790 * For some switch statements, gcc generates a jump table in the .rodata
 791 * section which contains a list of addresses within the function to jump to.
 792 * This finds these jump tables and adds them to the insn->alts lists.
 793 */
 794static int add_switch_table_alts(struct objtool_file *file)
 795{
 796        struct section *sec;
 797        struct symbol *func;
 798        int ret;
 799
 800        if (!file->rodata || !file->rodata->rela)
 801                return 0;
 802
 803        list_for_each_entry(sec, &file->elf->sections, list) {
 804                list_for_each_entry(func, &sec->symbol_list, list) {
 805                        if (func->type != STT_FUNC)
 806                                continue;
 807
 808                        ret = add_func_switch_tables(file, func);
 809                        if (ret)
 810                                return ret;
 811                }
 812        }
 813
 814        return 0;
 815}
 816
 817static int decode_sections(struct objtool_file *file)
 818{
 819        int ret;
 820
 821        ret = decode_instructions(file);
 822        if (ret)
 823                return ret;
 824
 825        add_ignores(file);
 826
 827        ret = add_jump_destinations(file);
 828        if (ret)
 829                return ret;
 830
 831        ret = add_call_destinations(file);
 832        if (ret)
 833                return ret;
 834
 835        ret = add_special_section_alts(file);
 836        if (ret)
 837                return ret;
 838
 839        ret = add_switch_table_alts(file);
 840        if (ret)
 841                return ret;
 842
 843        return 0;
 844}
 845
 846static bool is_fentry_call(struct instruction *insn)
 847{
 848        if (insn->type == INSN_CALL &&
 849            insn->call_dest->type == STT_NOTYPE &&
 850            !strcmp(insn->call_dest->name, "__fentry__"))
 851                return true;
 852
 853        return false;
 854}
 855
 856static bool has_modified_stack_frame(struct instruction *insn)
 857{
 858        return (insn->state & STATE_FP_SAVED) ||
 859               (insn->state & STATE_FP_SETUP);
 860}
 861
 862static bool has_valid_stack_frame(struct instruction *insn)
 863{
 864        return (insn->state & STATE_FP_SAVED) &&
 865               (insn->state & STATE_FP_SETUP);
 866}
 867
 868static unsigned int frame_state(unsigned long state)
 869{
 870        return (state & (STATE_FP_SAVED | STATE_FP_SETUP));
 871}
 872
 873/*
 874 * Follow the branch starting at the given instruction, and recursively follow
 875 * any other branches (jumps).  Meanwhile, track the frame pointer state at
 876 * each instruction and validate all the rules described in
 877 * tools/objtool/Documentation/stack-validation.txt.
 878 */
 879static int validate_branch(struct objtool_file *file,
 880                           struct instruction *first, unsigned char first_state)
 881{
 882        struct alternative *alt;
 883        struct instruction *insn;
 884        struct section *sec;
 885        struct symbol *func = NULL;
 886        unsigned char state;
 887        int ret;
 888
 889        insn = first;
 890        sec = insn->sec;
 891        state = first_state;
 892
 893        if (insn->alt_group && list_empty(&insn->alts)) {
 894                WARN_FUNC("don't know how to handle branch to middle of alternative instruction group",
 895                          sec, insn->offset);
 896                return 1;
 897        }
 898
 899        while (1) {
 900                if (file->c_file && insn->func) {
 901                        if (func && func != insn->func) {
 902                                WARN("%s() falls through to next function %s()",
 903                                     func->name, insn->func->name);
 904                                return 1;
 905                        }
 906
 907                        func = insn->func;
 908                }
 909
 910                if (insn->visited) {
 911                        if (frame_state(insn->state) != frame_state(state)) {
 912                                WARN_FUNC("frame pointer state mismatch",
 913                                          sec, insn->offset);
 914                                return 1;
 915                        }
 916
 917                        return 0;
 918                }
 919
 920                insn->visited = true;
 921                insn->state = state;
 922
 923                list_for_each_entry(alt, &insn->alts, list) {
 924                        ret = validate_branch(file, alt->insn, state);
 925                        if (ret)
 926                                return 1;
 927                }
 928
 929                switch (insn->type) {
 930
 931                case INSN_FP_SAVE:
 932                        if (!nofp) {
 933                                if (state & STATE_FP_SAVED) {
 934                                        WARN_FUNC("duplicate frame pointer save",
 935                                                  sec, insn->offset);
 936                                        return 1;
 937                                }
 938                                state |= STATE_FP_SAVED;
 939                        }
 940                        break;
 941
 942                case INSN_FP_SETUP:
 943                        if (!nofp) {
 944                                if (state & STATE_FP_SETUP) {
 945                                        WARN_FUNC("duplicate frame pointer setup",
 946                                                  sec, insn->offset);
 947                                        return 1;
 948                                }
 949                                state |= STATE_FP_SETUP;
 950                        }
 951                        break;
 952
 953                case INSN_FP_RESTORE:
 954                        if (!nofp) {
 955                                if (has_valid_stack_frame(insn))
 956                                        state &= ~STATE_FP_SETUP;
 957
 958                                state &= ~STATE_FP_SAVED;
 959                        }
 960                        break;
 961
 962                case INSN_RETURN:
 963                        if (!nofp && has_modified_stack_frame(insn)) {
 964                                WARN_FUNC("return without frame pointer restore",
 965                                          sec, insn->offset);
 966                                return 1;
 967                        }
 968                        return 0;
 969
 970                case INSN_CALL:
 971                        if (is_fentry_call(insn)) {
 972                                state |= STATE_FENTRY;
 973                                break;
 974                        }
 975
 976                        ret = dead_end_function(file, insn->call_dest);
 977                        if (ret == 1)
 978                                return 0;
 979                        if (ret == -1)
 980                                return 1;
 981
 982                        /* fallthrough */
 983                case INSN_CALL_DYNAMIC:
 984                        if (!nofp && !has_valid_stack_frame(insn)) {
 985                                WARN_FUNC("call without frame pointer save/setup",
 986                                          sec, insn->offset);
 987                                return 1;
 988                        }
 989                        break;
 990
 991                case INSN_JUMP_CONDITIONAL:
 992                case INSN_JUMP_UNCONDITIONAL:
 993                        if (insn->jump_dest) {
 994                                ret = validate_branch(file, insn->jump_dest,
 995                                                      state);
 996                                if (ret)
 997                                        return 1;
 998                        } else if (has_modified_stack_frame(insn)) {
 999                                WARN_FUNC("sibling call from callable instruction with changed frame pointer",
1000                                          sec, insn->offset);
1001                                return 1;
1002                        } /* else it's a sibling call */
1003
1004                        if (insn->type == INSN_JUMP_UNCONDITIONAL)
1005                                return 0;
1006
1007                        break;
1008
1009                case INSN_JUMP_DYNAMIC:
1010                        if (list_empty(&insn->alts) &&
1011                            has_modified_stack_frame(insn)) {
1012                                WARN_FUNC("sibling call from callable instruction with changed frame pointer",
1013                                          sec, insn->offset);
1014                                return 1;
1015                        }
1016
1017                        return 0;
1018
1019                case INSN_BUG:
1020                        return 0;
1021
1022                default:
1023                        break;
1024                }
1025
1026                insn = next_insn_same_sec(file, insn);
1027                if (!insn) {
1028                        WARN("%s: unexpected end of section", sec->name);
1029                        return 1;
1030                }
1031        }
1032
1033        return 0;
1034}
1035
1036static bool is_gcov_insn(struct instruction *insn)
1037{
1038        struct rela *rela;
1039        struct section *sec;
1040        struct symbol *sym;
1041        unsigned long offset;
1042
1043        rela = find_rela_by_dest_range(insn->sec, insn->offset, insn->len);
1044        if (!rela)
1045                return false;
1046
1047        if (rela->sym->type != STT_SECTION)
1048                return false;
1049
1050        sec = rela->sym->sec;
1051        offset = rela->addend + insn->offset + insn->len - rela->offset;
1052
1053        list_for_each_entry(sym, &sec->symbol_list, list) {
1054                if (sym->type != STT_OBJECT)
1055                        continue;
1056
1057                if (offset >= sym->offset && offset < sym->offset + sym->len)
1058                        return (!memcmp(sym->name, "__gcov0.", 8));
1059        }
1060
1061        return false;
1062}
1063
1064static bool is_kasan_insn(struct instruction *insn)
1065{
1066        return (insn->type == INSN_CALL &&
1067                !strcmp(insn->call_dest->name, "__asan_handle_no_return"));
1068}
1069
1070static bool is_ubsan_insn(struct instruction *insn)
1071{
1072        return (insn->type == INSN_CALL &&
1073                !strcmp(insn->call_dest->name,
1074                        "__ubsan_handle_builtin_unreachable"));
1075}
1076
1077static bool ignore_unreachable_insn(struct symbol *func,
1078                                    struct instruction *insn)
1079{
1080        int i;
1081
1082        if (insn->type == INSN_NOP)
1083                return true;
1084
1085        if (is_gcov_insn(insn))
1086                return true;
1087
1088        /*
1089         * Check if this (or a subsequent) instruction is related to
1090         * CONFIG_UBSAN or CONFIG_KASAN.
1091         *
1092         * End the search at 5 instructions to avoid going into the weeds.
1093         */
1094        for (i = 0; i < 5; i++) {
1095
1096                if (is_kasan_insn(insn) || is_ubsan_insn(insn))
1097                        return true;
1098
1099                if (insn->type == INSN_JUMP_UNCONDITIONAL && insn->jump_dest) {
1100                        insn = insn->jump_dest;
1101                        continue;
1102                }
1103
1104                if (insn->offset + insn->len >= func->offset + func->len)
1105                        break;
1106                insn = list_next_entry(insn, list);
1107        }
1108
1109        return false;
1110}
1111
1112static int validate_functions(struct objtool_file *file)
1113{
1114        struct section *sec;
1115        struct symbol *func;
1116        struct instruction *insn;
1117        int ret, warnings = 0;
1118
1119        list_for_each_entry(sec, &file->elf->sections, list) {
1120                list_for_each_entry(func, &sec->symbol_list, list) {
1121                        if (func->type != STT_FUNC)
1122                                continue;
1123
1124                        insn = find_insn(file, sec, func->offset);
1125                        if (!insn)
1126                                continue;
1127
1128                        ret = validate_branch(file, insn, 0);
1129                        warnings += ret;
1130                }
1131        }
1132
1133        list_for_each_entry(sec, &file->elf->sections, list) {
1134                list_for_each_entry(func, &sec->symbol_list, list) {
1135                        if (func->type != STT_FUNC)
1136                                continue;
1137
1138                        func_for_each_insn(file, func, insn) {
1139                                if (insn->visited)
1140                                        continue;
1141
1142                                insn->visited = true;
1143
1144                                if (file->ignore_unreachables || warnings ||
1145                                    ignore_unreachable_insn(func, insn))
1146                                        continue;
1147
1148                                WARN_FUNC("function has unreachable instruction", insn->sec, insn->offset);
1149                                warnings++;
1150                        }
1151                }
1152        }
1153
1154        return warnings;
1155}
1156
1157static int validate_uncallable_instructions(struct objtool_file *file)
1158{
1159        struct instruction *insn;
1160        int warnings = 0;
1161
1162        for_each_insn(file, insn) {
1163                if (!insn->visited && insn->type == INSN_RETURN) {
1164                        WARN_FUNC("return instruction outside of a callable function",
1165                                  insn->sec, insn->offset);
1166                        warnings++;
1167                }
1168        }
1169
1170        return warnings;
1171}
1172
1173static void cleanup(struct objtool_file *file)
1174{
1175        struct instruction *insn, *tmpinsn;
1176        struct alternative *alt, *tmpalt;
1177
1178        list_for_each_entry_safe(insn, tmpinsn, &file->insn_list, list) {
1179                list_for_each_entry_safe(alt, tmpalt, &insn->alts, list) {
1180                        list_del(&alt->list);
1181                        free(alt);
1182                }
1183                list_del(&insn->list);
1184                hash_del(&insn->hash);
1185                free(insn);
1186        }
1187        elf_close(file->elf);
1188}
1189
1190const char * const check_usage[] = {
1191        "objtool check [<options>] file.o",
1192        NULL,
1193};
1194
1195int cmd_check(int argc, const char **argv)
1196{
1197        struct objtool_file file;
1198        int ret, warnings = 0;
1199
1200        const struct option options[] = {
1201                OPT_BOOLEAN('f', "no-fp", &nofp, "Skip frame pointer validation"),
1202                OPT_END(),
1203        };
1204
1205        argc = parse_options(argc, argv, options, check_usage, 0);
1206
1207        if (argc != 1)
1208                usage_with_options(check_usage, options);
1209
1210        objname = argv[0];
1211
1212        file.elf = elf_open(objname);
1213        if (!file.elf) {
1214                fprintf(stderr, "error reading elf file %s\n", objname);
1215                return 1;
1216        }
1217
1218        INIT_LIST_HEAD(&file.insn_list);
1219        hash_init(file.insn_hash);
1220        file.whitelist = find_section_by_name(file.elf, "__func_stack_frame_non_standard");
1221        file.rodata = find_section_by_name(file.elf, ".rodata");
1222        file.ignore_unreachables = false;
1223        file.c_file = find_section_by_name(file.elf, ".comment");
1224
1225        ret = decode_sections(&file);
1226        if (ret < 0)
1227                goto out;
1228        warnings += ret;
1229
1230        ret = validate_functions(&file);
1231        if (ret < 0)
1232                goto out;
1233        warnings += ret;
1234
1235        ret = validate_uncallable_instructions(&file);
1236        if (ret < 0)
1237                goto out;
1238        warnings += ret;
1239
1240out:
1241        cleanup(&file);
1242
1243        /* ignore warnings for now until we get all the code cleaned up */
1244        if (ret || warnings)
1245                return 0;
1246        return 0;
1247}
1248