Commit Graph

86 Commits

Author SHA1 Message Date
Waiman Long 7001b4c3c6 objtool: Fix find_{symbol,func}_containing()
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2190342
Conflicts: A minor context diff in the elf_add_symbol() hunk of
	   tools/objtool/elf.c due to the presence of a later
	   upstream commit 19526717f768 ("objtool: Optimize
	   elf_dirty_reloc_sym()").

commit 5da6aea375cde499fdfac3cde4f26df4a840eb9f
Author: Peter Zijlstra <peterz@infradead.org>
Date:   Thu, 15 Sep 2022 13:11:12 +0200

    objtool: Fix find_{symbol,func}_containing()

    The current find_{symbol,func}_containing() functions are broken in
    the face of overlapping symbols, exactly the case that is needed for a
    new ibt/endbr supression.

    Import interval_tree_generic.h into the tools tree and convert the
    symbol tree to an interval tree to support proper range stabs.

    Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
    Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
    Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
    Link: https://lore.kernel.org/r/20220915111146.330203761@infradead.org

Signed-off-by: Waiman Long <longman@redhat.com>
2023-06-30 20:17:18 -04:00
Joe Lawrence a56134a6c9 objtool: Optimize elf_dirty_reloc_sym()
JIRA: https://issues.redhat.com/browse/RHEL-255

commit 19526717f768bf2f89ca01bd2a595728ebe57540
Author: Peter Zijlstra <peterz@infradead.org>
Date:   Wed Nov 2 22:31:19 2022 +0100

    objtool: Optimize elf_dirty_reloc_sym()

    When moving a symbol in the symtab its index changes and any reloc
    referring that symtol-table-index will need to be rewritten too.

    In order to facilitate this, objtool simply marks the whole reloc
    section 'changed' which will cause the whole section to be
    re-generated.

    However, finding the relocs that use any given symbol is implemented
    rather crudely -- a fully iteration of all sections and their relocs.
    Given that some builds have over 20k sections (kallsyms etc..)
    iterating all that for *each* symbol moved takes a bit of time.

    Instead have each symbol keep a list of relocs that reference it.

    This *vastly* improves build times for certain configs.

    Reported-by: Borislav Petkov <bp@alien8.de>
    Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
    Link: https://lkml.kernel.org/r/Y2LlRA7x+8UsE1xf@hirez.programming.kicks-ass.net

Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
2023-05-18 15:09:34 -04:00
Joe Lawrence 668a93c951 objtool: Add option to generate prefix symbols
JIRA: https://issues.redhat.com/browse/RHEL-255

commit 9f2899fe36a623885d8576604cb582328ad32b3c
Author: Peter Zijlstra <peterz@infradead.org>
Date:   Fri Oct 28 15:50:42 2022 +0200

    objtool: Add option to generate prefix symbols

    When code is compiled with:

      -fpatchable-function-entry=${PADDING_BYTES},${PADDING_BYTES}

    functions will have PADDING_BYTES of NOP in front of them. Unwinders
    and other things that symbolize code locations will typically
    attribute these bytes to the preceding function.

    Given that these bytes nominally belong to the following symbol this
    mis-attribution is confusing.

    Inspired by the fact that CFI_CLANG emits __cfi_##name symbols to
    claim these bytes, allow objtool to emit __pfx_##name symbols to do
    the same.

    Therefore add the objtool --prefix=N argument, to conditionally place
    a __pfx_##name symbol at N bytes ahead of symbol 'name' when: all
    these preceding bytes are NOP and name-N is an instruction boundary.

    Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
    Tested-by: Yujie Liu <yujie.liu@intel.com>
    Link: https://lkml.kernel.org/r/20221028194453.526899822@infradead.org

Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
2023-05-18 15:09:34 -04:00
Joe Lawrence 17dde516e8 objtool: Avoid O(bloody terrible) behaviour -- an ode to libelf
JIRA: https://issues.redhat.com/browse/RHEL-255

Conflicts:
	tools/objtool/include/objtool/elf.h
	- cs-9 doesn't have 6644ee846cb9 ("objtool: Track init
	  section"), which introduced the init flag in struct section

commit 13f60e80e15dd0657c90bcca372ba045630ed9de
Author: Peter Zijlstra <peterz@infradead.org>
Date:   Fri Oct 28 20:29:51 2022 +0200

    objtool: Avoid O(bloody terrible) behaviour -- an ode to libelf

    Due to how gelf_update_sym*() requires an Elf_Data pointer, and how
    libelf keeps Elf_Data in a linked list per section,
    elf_update_symbol() ends up having to iterate this list on each
    update to find the correct Elf_Data for the index'ed symbol.

    By allocating one Elf_Data per new symbol, the list grows per new
    symbol, giving an effective O(n^2) insertion time. This is obviously
    bloody terrible.

    Therefore over-allocate the Elf_Data when an extention is needed.
    Except it turns out libelf disregards Elf_Scn::sh_size in favour of
    the sum of Elf_Data::d_size. IOW it will happily write out all the
    unused space and fill it with:

      0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND

    entries (aka zeros). Which obviously violates the STB_LOCAL placement
    rule, and is a general pain in the backside for not being the desired
    behaviour.

    Manually fix-up the Elf_Data size to avoid this problem before calling
    elf_update().

    This significantly improves performance when adding a significant
    number of symbols.

    Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
    Tested-by: Yujie Liu <yujie.liu@intel.com>
    Link: https://lkml.kernel.org/r/20221028194453.461658986@infradead.org

Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
2023-05-18 15:09:34 -04:00
Joe Lawrence d0e56608e2 objtool: Slice up elf_create_section_symbol()
JIRA: https://issues.redhat.com/browse/RHEL-255

commit 4c91be8e926c6b3734d59b9348e305431484d42b
Author: Peter Zijlstra <peterz@infradead.org>
Date:   Fri Oct 28 15:49:26 2022 +0200

    objtool: Slice up elf_create_section_symbol()

    In order to facilitate creation of more symbol types, slice up
    elf_create_section_symbol() to extract a generic helper that deals
    with adding ELF symbols.

    Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
    Tested-by: Yujie Liu <yujie.liu@intel.com>
    Link: https://lkml.kernel.org/r/20221028194453.396634875@infradead.org

Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
2023-05-18 15:09:34 -04:00
Joe Lawrence 16fd46611e objtool: Fix objtool regression on x32 systems
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2121207

commit 22682a07acc308ef78681572e19502ce8893c4d4
Author: Mikulas Patocka <mpatocka@redhat.com>
Date:   Mon May 16 11:06:36 2022 -0400

    objtool: Fix objtool regression on x32 systems

    Commit c087c6e7b551 ("objtool: Fix type of reloc::addend") failed to
    appreciate cross building from ILP32 hosts, where 'int' == 'long' and
    the issue persists.

    As such, use s64/int64_t/Elf64_Sxword for this field and suffer the
    pain that is ISO C99 printf formats for it.

    Fixes: c087c6e7b551 ("objtool: Fix type of reloc::addend")
    Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
    [peterz: reword changelog, s/long long/s64/]
    Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
    Signed-off-by: Borislav Petkov <bp@suse.de>
    Cc: <stable@vger.kernel.org>
    Link: https://lkml.kernel.org/r/alpine.LRH.2.02.2205161041260.11556@file01.intranet.prod.int.rdu2.redhat.com

Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
2022-10-27 15:26:53 -04:00
Joe Lawrence 8ac61e2b15 objtool: Preserve special st_shndx indexes in elf_update_symbol
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2121207

commit 5141d3a06b2da1731ac82091298b766a1f95d3d8
Author: Sami Tolvanen <samitolvanen@google.com>
Date:   Thu Sep 8 14:54:58 2022 -0700

    objtool: Preserve special st_shndx indexes in elf_update_symbol

    elf_update_symbol fails to preserve the special st_shndx values
    between [SHN_LORESERVE, SHN_HIRESERVE], which results in it
    converting SHN_ABS entries into SHN_UNDEF, for example. Explicitly
    check for the special indexes and ensure these symbols are not
    marked undefined.

    Fixes: ead165fa1042 ("objtool: Fix symbol creation")
    Signed-off-by: Sami Tolvanen <samitolvanen@google.com>
    Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
    Tested-by: Peter Zijlstra (Intel) <peterz@infradead.org>
    Signed-off-by: Kees Cook <keescook@chromium.org>
    Link: https://lore.kernel.org/r/20220908215504.3686827-17-samitolvanen@google.com

Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
2022-10-27 15:26:53 -04:00
Joe Lawrence ff9faf159e objtool: Fix symbol creation
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2121207

commit ead165fa1042247b033afad7be4be9b815d04ade
Author: Peter Zijlstra <peterz@infradead.org>
Date:   Tue May 17 17:42:04 2022 +0200

    objtool: Fix symbol creation

    Nathan reported objtool failing with the following messages:

      warning: objtool: no non-local symbols !?
      warning: objtool: gelf_update_symshndx: invalid section index

    The problem is due to commit 4abff6d48dbc ("objtool: Fix code relocs
    vs weak symbols") failing to consider the case where an object would
    have no non-local symbols.

    The problem that commit tries to address is adding a STB_LOCAL symbol
    to the symbol table in light of the ELF spec's requirement that:

      In each symbol table, all symbols with STB_LOCAL binding preced the
      weak and global symbols.  As ``Sections'' above describes, a symbol
      table section's sh_info section header member holds the symbol table
      index for the first non-local symbol.

    The approach taken is to find this first non-local symbol, move that
    to the end and then re-use the freed spot to insert a new local symbol
    and increment sh_info.

    Except it never considered the case of object files without global
    symbols and got a whole bunch of details wrong -- so many in fact that
    it is a wonder it ever worked :/

    Specifically:

     - It failed to re-hash the symbol on the new index, so a subsequent
       find_symbol_by_index() would not find it at the new location and a
       query for the old location would now return a non-deterministic
       choice between the old and new symbol.

     - It failed to appreciate that the GElf wrappers are not a valid disk
       format (it works because GElf is basically Elf64 and we only
       support x86_64 atm.)

     - It failed to fully appreciate how horrible the libelf API really is
       and got the gelf_update_symshndx() call pretty much completely
       wrong; with the direct consequence that if inserting a second
       STB_LOCAL symbol would require moving the same STB_GLOBAL symbol
       again it would completely come unstuck.

    Write a new elf_update_symbol() function that wraps all the magic
    required to update or create a new symbol at a given index.

    Specifically, gelf_update_sym*() require an @ndx argument that is
    relative to the @data argument; this means you have to manually
    iterate the section data descriptor list and update @ndx.

    Fixes: 4abff6d48dbc ("objtool: Fix code relocs vs weak symbols")
    Reported-by: Nathan Chancellor <nathan@kernel.org>
    Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
    Signed-off-by: Borislav Petkov <bp@suse.de>
    Acked-by: Josh Poimboeuf <jpoimboe@kernel.org>
    Tested-by: Nathan Chancellor <nathan@kernel.org>
    Cc: <stable@vger.kernel.org>
    Link: https://lkml.kernel.org/r/YoPCTEYjoPqE4ZxB@hirez.programming.kicks-ass.net

Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
2022-10-27 15:26:52 -04:00
Joe Lawrence 4452c87386 objtool: Remove --lto and --vmlinux in favor of --link
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2121207
Conflicts:
	scripts/Makefile.build
	- rhel9 doesn't have d31ed5d767c0 ("kbuild: Fixup the IBT kbuild
	  changes")

commit 753da4179d08b625d8df72e97724e22749969fd3
Author: Josh Poimboeuf <jpoimboe@redhat.com>
Date:   Mon Apr 18 09:50:43 2022 -0700

    objtool: Remove --lto and --vmlinux in favor of --link

    The '--lto' option is a confusing way of telling objtool to do stack
    validation despite it being a linked object.  It's no longer needed now
    that an explicit '--stackval' option exists.  The '--vmlinux' option is
    also redundant.

    Remove both options in favor of a straightforward '--link' option which
    identifies a linked object.

    Also, implicitly set '--link' with a warning if the user forgets to do
    so and we can tell that it's a linked object.  This makes it easier for
    manual vmlinux runs.

    Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
    Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
    Reviewed-by: Miroslav Benes <mbenes@suse.cz>
    Link: https://lkml.kernel.org/r/dcd3ceffd15a54822c6183e5766d21ad06082b45.1650300597.git.jpoimboe@redhat.com

Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
2022-10-27 15:26:52 -04:00
Joe Lawrence 330dad14bf objtool: Reorganize cmdline options
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2121207
Conflicts:
	scripts/Makefile.build
	- rhel9 already has CONFIG_RETHUNK from upstream f43b9876e857
	  ("x86/retbleed: Add fine grained Kconfig knobs")

	tools/objtool/builtin-check.c
	- rhel9 already has upstream f43b9876e857 ("x86/retbleed: Add fine
	  grained Kconfig knobs"), which added --rethunk option

	tools/objtool/check.c
	tools/objtool/include/objtool/builtin.h
	- rhel9 already has upstream f43b9876e857 ("x86/retbleed: Add fine
	  grained Kconfig knobs"), account for rethunk code

commit 2daf7faba7ded8703e4b4ebc8b161f22272fc91a
Author: Josh Poimboeuf <jpoimboe@redhat.com>
Date:   Mon Apr 18 09:50:26 2022 -0700

    objtool: Reorganize cmdline options

    Split the existing options into two groups: actions, which actually do
    something; and options, which modify the actions in some way.

    Also there's no need to have short flags for all the non-action options.
    Reserve short flags for the more important actions.

    While at it:

    - change a few of the short flags to be more intuitive

    - make option descriptions more consistently descriptive

    - sort options in the source like they are when printed

    - move options to a global struct

    Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
    Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
    Reviewed-by: Miroslav Benes <mbenes@suse.cz>
    Link: https://lkml.kernel.org/r/9dcaa752f83aca24b1b21f0b0eeb28a0c181c0b0.1650300597.git.jpoimboe@redhat.com

Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
2022-10-27 15:26:51 -04:00
Joe Lawrence be5305cc16 objtool: Fix type of reloc::addend
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2121207

commit c087c6e7b551b7f208c0b852304f044954cf2bb3
Author: Peter Zijlstra <peterz@infradead.org>
Date:   Sun Apr 17 17:03:40 2022 +0200

    objtool: Fix type of reloc::addend

    Elf{32,64}_Rela::r_addend is of type: Elf{32,64}_Sword, that means
    that our reloc::addend needs to be long or face tuncation issues when
    we do elf_rebuild_reloc_section():

      - 107:  48 b8 00 00 00 00 00 00 00 00   movabs $0x0,%rax        109: R_X86_64_64        level4_kernel_pgt+0x80000067
      + 107:  48 b8 00 00 00 00 00 00 00 00   movabs $0x0,%rax        109: R_X86_64_64        level4_kernel_pgt-0x7fffff99

    Fixes: 627fce1480 ("objtool: Add ORC unwind table generation")
    Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
    Acked-by: Josh Poimboeuf <jpoimboe@redhat.com>
    Link: https://lkml.kernel.org/r/20220419203807.596871927@infradead.org

Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
2022-10-27 15:26:49 -04:00
Joe Lawrence 25e26f98cb objtool: Fix code relocs vs weak symbols
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2121207

commit 4abff6d48dbcea8200c7ea35ba70c242d128ebf3
Author: Peter Zijlstra <peterz@infradead.org>
Date:   Sun Apr 17 17:03:36 2022 +0200

    objtool: Fix code relocs vs weak symbols

    Occasionally objtool driven code patching (think .static_call_sites
    .retpoline_sites etc..) goes sideways and it tries to patch an
    instruction that doesn't match.

    Much head-scatching and cursing later the problem is as outlined below
    and affects every section that objtool generates for us, very much
    including the ORC data. The below uses .static_call_sites because it's
    convenient for demonstration purposes, but as mentioned the ORC
    sections, .retpoline_sites and __mount_loc are all similarly affected.

    Consider:

    foo-weak.c:

      extern void __SCT__foo(void);

      __attribute__((weak)) void foo(void)
      {
              return __SCT__foo();
      }

    foo.c:

      extern void __SCT__foo(void);
      extern void my_foo(void);

      void foo(void)
      {
              my_foo();
              return __SCT__foo();
      }

    These generate the obvious code
    (gcc -O2 -fcf-protection=none -fno-asynchronous-unwind-tables -c foo*.c):

    foo-weak.o:
    0000000000000000 <foo>:
       0:   e9 00 00 00 00          jmpq   5 <foo+0x5>      1: R_X86_64_PLT32       __SCT__foo-0x4

    foo.o:
    0000000000000000 <foo>:
       0:   48 83 ec 08             sub    $0x8,%rsp
       4:   e8 00 00 00 00          callq  9 <foo+0x9>      5: R_X86_64_PLT32       my_foo-0x4
       9:   48 83 c4 08             add    $0x8,%rsp
       d:   e9 00 00 00 00          jmpq   12 <foo+0x12>    e: R_X86_64_PLT32       __SCT__foo-0x4

    Now, when we link these two files together, you get something like
    (ld -r -o foos.o foo-weak.o foo.o):

    foos.o:
    0000000000000000 <foo-0x10>:
       0:   e9 00 00 00 00          jmpq   5 <foo-0xb>      1: R_X86_64_PLT32       __SCT__foo-0x4
       5:   66 2e 0f 1f 84 00 00 00 00 00   nopw   %cs:0x0(%rax,%rax,1)
       f:   90                      nop

    0000000000000010 <foo>:
      10:   48 83 ec 08             sub    $0x8,%rsp
      14:   e8 00 00 00 00          callq  19 <foo+0x9>     15: R_X86_64_PLT32      my_foo-0x4
      19:   48 83 c4 08             add    $0x8,%rsp
      1d:   e9 00 00 00 00          jmpq   22 <foo+0x12>    1e: R_X86_64_PLT32      __SCT__foo-0x4

    Noting that ld preserves the weak function text, but strips the symbol
    off of it (hence objdump doing that funny negative offset thing). This
    does lead to 'interesting' unused code issues with objtool when ran on
    linked objects, but that seems to be working (fingers crossed).

    So far so good.. Now lets consider the objtool static_call output
    section (readelf output, old binutils):

    foo-weak.o:

    Relocation section '.rela.static_call_sites' at offset 0x2c8 contains 1 entry:
        Offset             Info             Type               Symbol's Value  Symbol's Name + Addend
    0000000000000000  0000000200000002 R_X86_64_PC32          0000000000000000 .text + 0
    0000000000000004  0000000d00000002 R_X86_64_PC32          0000000000000000 __SCT__foo + 1

    foo.o:

    Relocation section '.rela.static_call_sites' at offset 0x310 contains 2 entries:
        Offset             Info             Type               Symbol's Value  Symbol's Name + Addend
    0000000000000000  0000000200000002 R_X86_64_PC32          0000000000000000 .text + d
    0000000000000004  0000000d00000002 R_X86_64_PC32          0000000000000000 __SCT__foo + 1

    foos.o:

    Relocation section '.rela.static_call_sites' at offset 0x430 contains 4 entries:
        Offset             Info             Type               Symbol's Value  Symbol's Name + Addend
    0000000000000000  0000000100000002 R_X86_64_PC32          0000000000000000 .text + 0
    0000000000000004  0000000d00000002 R_X86_64_PC32          0000000000000000 __SCT__foo + 1
    0000000000000008  0000000100000002 R_X86_64_PC32          0000000000000000 .text + 1d
    000000000000000c  0000000d00000002 R_X86_64_PC32          0000000000000000 __SCT__foo + 1

    So we have two patch sites, one in the dead code of the weak foo and one
    in the real foo. All is well.

    *HOWEVER*, when the toolchain strips unused section symbols it
    generates things like this (using new enough binutils):

    foo-weak.o:

    Relocation section '.rela.static_call_sites' at offset 0x2c8 contains 1 entry:
        Offset             Info             Type               Symbol's Value  Symbol's Name + Addend
    0000000000000000  0000000200000002 R_X86_64_PC32          0000000000000000 foo + 0
    0000000000000004  0000000d00000002 R_X86_64_PC32          0000000000000000 __SCT__foo + 1

    foo.o:

    Relocation section '.rela.static_call_sites' at offset 0x310 contains 2 entries:
        Offset             Info             Type               Symbol's Value  Symbol's Name + Addend
    0000000000000000  0000000200000002 R_X86_64_PC32          0000000000000000 foo + d
    0000000000000004  0000000d00000002 R_X86_64_PC32          0000000000000000 __SCT__foo + 1

    foos.o:

    Relocation section '.rela.static_call_sites' at offset 0x430 contains 4 entries:
        Offset             Info             Type               Symbol's Value  Symbol's Name + Addend
    0000000000000000  0000000100000002 R_X86_64_PC32          0000000000000000 foo + 0
    0000000000000004  0000000d00000002 R_X86_64_PC32          0000000000000000 __SCT__foo + 1
    0000000000000008  0000000100000002 R_X86_64_PC32          0000000000000000 foo + d
    000000000000000c  0000000d00000002 R_X86_64_PC32          0000000000000000 __SCT__foo + 1

    And now we can see how that foos.o .static_call_sites goes side-ways, we
    now have _two_ patch sites in foo. One for the weak symbol at foo+0
    (which is no longer a static_call site!) and one at foo+d which is in
    fact the right location.

    This seems to happen when objtool cannot find a section symbol, in which
    case it falls back to any other symbol to key off of, however in this
    case that goes terribly wrong!

    As such, teach objtool to create a section symbol when there isn't
    one.

    Fixes: 44f6a7c075 ("objtool: Fix seg fault with Clang non-section symbols")
    Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
    Acked-by: Josh Poimboeuf <jpoimboe@redhat.com>
    Link: https://lkml.kernel.org/r/20220419203807.655552918@infradead.org

Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
2022-10-27 15:26:49 -04:00
Joe Lawrence 9029b20380 objtool: Ignore extra-symbol code
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2121207

commit 4adb23686795e9c88e3217b5d7b4524c0da9d04f
Author: Peter Zijlstra <peterz@infradead.org>
Date:   Tue Mar 8 16:30:46 2022 +0100

    objtool: Ignore extra-symbol code

    There's a fun implementation detail on linking STB_WEAK symbols. When
    the linker combines two translation units, where one contains a weak
    function and the other an override for it. It simply strips the
    STB_WEAK symbol from the symbol table, but doesn't actually remove the
    code.

    The result is that when objtool is ran in a whole-archive kind of way,
    it will encounter *heaps* of unused (and unreferenced) code. All
    rudiments of weak functions.

    Additionally, when a weak implementation is split into a .cold
    subfunction that .cold symbol is left in place, even though completely
    unused.

    Teach objtool to ignore such rudiments by searching for symbol holes;
    that is, code ranges that fall outside the given symbol bounds.
    Specifically, ignore a sequence of unreachable instruction iff they
    occupy a single hole, additionally ignore any .cold subfunctions
    referenced.

    Both ld.bfd and ld.lld behave like this. LTO builds otoh can (and do)
    properly DCE weak functions.

    Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
    Acked-by: Josh Poimboeuf <jpoimboe@redhat.com>
    Link: https://lore.kernel.org/r/20220308154319.232019347@infradead.org

Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
2022-10-27 14:27:58 -04:00
Joe Lawrence 89ef135a9b objtool: Add --dry-run
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2121207
Conflicts:
	tools/objtool/builtin-check.c
	tools/objtool/include/objtool/builtin.h
	- rhel9 already contains backport of upstream f43b9876e857
	 ("x86/retbleed: Add fine grained Kconfig knobs"), which added
	 rethunk option

commit f2d3a250897133cc36c13a641bd6a9b4dd5ad234
Author: Peter Zijlstra <peterz@infradead.org>
Date:   Tue Mar 8 16:30:13 2022 +0100

    objtool: Add --dry-run

    Add a --dry-run argument to skip writing the modifications. This is
    convenient for debugging.

    Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
    Reviewed-by: Kees Cook <keescook@chromium.org>
    Reviewed-by: Miroslav Benes <mbenes@suse.cz>
    Acked-by: Josh Poimboeuf <jpoimboe@redhat.com>
    Link: https://lore.kernel.org/r/20220308154317.282720146@infradead.org

Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
2022-10-27 14:27:56 -04:00
Joe Lawrence b2bb84e508 objtool: Update section header before relocations
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2121207

commit 86e1e054e0d2105cf32b0266cf1a64e6c26424f7
Author: Michael Forney <mforney@mforney.org>
Date:   Sat May 8 17:01:03 2021 -0700

    objtool: Update section header before relocations

    The libelf implementation from elftoolchain has a safety check in
    gelf_update_rel[a] to check that the data corresponds to a section
    that has type SHT_REL[A] [0]. If the relocation is updated before
    the section header is updated with the proper type, this check
    fails.

    To fix this, update the section header first, before the relocations.
    Previously, the section size was calculated in elf_rebuild_reloc_section
    by counting the number of entries in the reloc_list. However, we
    now need the size during elf_write so instead keep a running total
    and add to it for every new relocation.

    [0] https://sourceforge.net/p/elftoolchain/mailman/elftoolchain-developers/thread/CAGw6cBtkZro-8wZMD2ULkwJ39J+tHtTtAWXufMjnd3cQ7XG54g@mail.gmail.com/

    Signed-off-by: Michael Forney <mforney@mforney.org>
    Reviewed-by: Miroslav Benes <mbenes@suse.cz>
    Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
    Link: https://lore.kernel.org/r/20210509000103.11008-2-mforney@mforney.org

Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
2022-10-27 14:27:54 -04:00
Joe Lawrence bfff6d377e objtool: Check for gelf_update_rel[a] failures
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2121207

commit b46179d6bb3182c020f2bf9bb4df6ba5463b0495
Author: Michael Forney <mforney@mforney.org>
Date:   Sat May 8 17:01:02 2021 -0700

    objtool: Check for gelf_update_rel[a] failures

    Otherwise, if these fail we end up with garbage data in the
    .rela.orc_unwind_ip section, leading to errors like

      ld: fs/squashfs/namei.o: bad reloc symbol index (0x7f16 >= 0x12) for offset 0x7f16d5c82cc8 in section `.orc_unwind_ip'

    Signed-off-by: Michael Forney <mforney@mforney.org>
    Reviewed-by: Miroslav Benes <mbenes@suse.cz>
    Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
    Link: https://lore.kernel.org/r/20210509000103.11008-1-mforney@mforney.org

Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
2022-10-27 14:27:54 -04:00
Waiman Long c4b23cb360 objtool: Fix pv_ops noinstr validation
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2090231

commit 988f01683c7f2bf9f8fe2bae1cf4010fcd1baaf5
Author: Peter Zijlstra <peterz@infradead.org>
Date:   Thu, 2 Dec 2021 21:45:34 +0100

    objtool: Fix pv_ops noinstr validation

    Boris reported that in one of his randconfig builds, objtool got
    infinitely stuck. Turns out there's trivial list corruption in the
    pv_ops tracking when a function is both in a static table and in a code
    assignment.

    Avoid re-adding function to the pv_ops[] lists when they're already on
    it.

    Fixes: db2b0c5d7b6f ("objtool: Support pv_opsindirect calls for noinstr")
    Reported-by: Borislav Petkov <bp@alien8.de>
    Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
    Signed-off-by: Borislav Petkov <bp@suse.de>
    Tested-by: Borislav Petkov <bp@alien8.de>
    Link: https://lkml.kernel.org/r/20211202204534.GA16608@worktop.programming.kicks-ass.net

Signed-off-by: Waiman Long <longman@redhat.com>
2022-07-29 11:55:51 -04:00
Waiman Long 635aed6f8d objtool,x86: Replace alternatives with .retpoline_sites
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2090231

commit 134ab5bd1883312d7a4b3033b05c6b5a1bb8889b
Author: Peter Zijlstra <peterz@infradead.org>
Date:   Tue, 26 Oct 2021 14:01:36 +0200

    objtool,x86: Replace alternatives with .retpoline_sites

    Instead of writing complete alternatives, simply provide a list of all
    the retpoline thunk calls. Then the kernel is free to do with them as
    it pleases. Simpler code all-round.

    Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
    Reviewed-by: Borislav Petkov <bp@suse.de>
    Acked-by: Josh Poimboeuf <jpoimboe@redhat.com>
    Tested-by: Alexei Starovoitov <ast@kernel.org>
    Link: https://lore.kernel.org/r/20211026120309.850007165@infradead.org

Signed-off-by: Waiman Long <longman@redhat.com>
2022-07-29 11:55:46 -04:00
C. Erastus Toe e72e1754a2 objtool: Remove redundant 'len' field from struct section
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2002440

commit fe255fe6ad97685e5a4be0d871f43288dbc10ad6
Author: Joe Lawrence <joe.lawrence@redhat.com>
Date:   Sun Aug 22 18:50:37 2021 -0400

    objtool: Remove redundant 'len' field from struct section

    The section structure already contains sh_size, so just remove the extra
    'len' member that requires extra mirroring and potential confusion.

    Suggested-by: Josh Poimboeuf <jpoimboe@redhat.com>
    Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
    Reviewed-by: Miroslav Benes <mbenes@suse.cz>
    Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
    Link: https://lore.kernel.org/r/20210822225037.54620-3-joe.lawrence@redhat.com
    Cc: Andy Lavr <andy.lavr@gmail.com>
    Cc: Peter Zijlstra <peterz@infradead.org>
    Cc: x86@kernel.org
    Cc: linux-kernel@vger.kernel.org

Signed-off-by: C. Erastus Toe <ctoe@redhat.com>
2021-10-28 17:14:14 -04:00
Linus Torvalds b89c07dea1 A single ELF format fix for a section flags mismatch bug that breaks
kernel tooling such as kpatch-build.
 
 Signed-off-by: Ingo Molnar <mingo@kernel.org>
 -----BEGIN PGP SIGNATURE-----
 
 iQJFBAABCgAvFiEEBpT5eoXrXCwVQwEKEnMQ0APhK1gFAmDZYv4RHG1pbmdvQGtl
 cm5lbC5vcmcACgkQEnMQ0APhK1ipeBAAhJPS/kCQ17Y5zGyMB0/6yfCWIifODoS7
 9J+6/mqKHPDdV07yzPtOXuTTmpKV4OHPi8Yj8kaXs5L5fOmQ1uAwITwZNF5hU0a5
 CiFIsubUCJmglf9b6L9EH5pBEQ72Cq4u8zIhJ9LmZ4t625AHJAm2ikZgascc4U67
 RvVoGr5sYTo0YEsc1IDM1wUtnUhXBNjS1VwkXNnCFFTXYHju47MeY1sPHq2hvkzO
 iJGC9A+hxfM1eQt9/qC/2L/6F/XECN61gcR9Get8TkWeEGHmPG+FthmPLd4oO9Ho
 03J4JfMbmXumWosAeilYBNUkfii/M5Em78Wpv/cB94iSt67rq7Eb+8gm4D5svmfN
 l+utsPY/HYB+uWV0hy2cV/ORRiwcJnon54dEWL6912YkKz+OIb3DK/7l9ex5lW+D
 r3o8NP0s6S+RgUkOFxz5VaYK1giu6fiaFysWdKeflvwlvY/64owMepQ1QfPBbeB7
 3DTzvuYZ4Cb1x/vR6WBbFqGcuJKZ1CsZIBLCblveUs+G0wlu147K5E1qlXg/Wvq7
 5Vzznc4fmRng8np5hxAw8ieLkatWg7szyryUV/4H2Ubs/jWGcH628ZYbapaCb7EM
 Eson65xzbVfhnz16z8sN13XIF1lGe8sb0+qiFSclEfyDUnZDuhwMn6d9Ubqxrg5J
 uTULEzmY/rI=
 =MvPd
 -----END PGP SIGNATURE-----
mergetag object d33b9035e1
 type commit
 tag objtool-core-2021-06-28
 tagger Ingo Molnar <mingo@kernel.org> 1624859477 +0200
 
 The biggest change in this cycle is the new code to handle
 and rewrite variable sized jump labels - which results in
 slightly tighter code generation in hot paths, through the
 use of short(er) NOPs.
 
 Also a number of cleanups and fixes, and a change to the
 generic include/linux/compiler.h to handle a s390 GCC quirk.
 
 Signed-off-by: Ingo Molnar <mingo@kernel.org>
 -----BEGIN PGP SIGNATURE-----
 
 iQJFBAABCgAvFiEEBpT5eoXrXCwVQwEKEnMQ0APhK1gFAmDZZGcRHG1pbmdvQGtl
 cm5lbC5vcmcACgkQEnMQ0APhK1goYg/7BxUIJXP0F5wbrMbAvJIDRgR/j3TA+ztk
 uNU1yabBGluMxCqJ87HadJ+A5d010G+GRUn/birVr7w1UuwWv8HOda78dnyG7tme
 xm78/1FlOnstuOTQxhK6rjbb2cp+QOmdsAQkq1TF4SOxArBQiwtjiOvytHjb5yNx
 7LrlbtuZ7Dtc0qd2evkG4ma4QkGoDhBS1dRogrItc27ZLuFIQoNnEd2K2QNMgczw
 a/Jx8fgNmdoJSq+vkBn9TnS/cJYUW/PAlPNtO3ac8yE857aDIVnjXFRzveAP/nTh
 rwFD6aCGnJAqyqP7A8ElNjySos5O+ebYApxe7rEx0TNLbrc55qSP9lpdIO+vgytV
 Xzy4O7z6o+lailQ4EoF8Qf+rlPeue0kLF23SsNbZY1uT0vjX1Uv70xgKbkuyPygp
 GNXAy6dOXK0AfaZYL/Wa50yVnJnkYDjes/hHr+HEam5Oad566pqIyQNP8yWSPqaf
 KHkL//1pb5C2RKwot4IYv/ftHfZB5QftoFq6bhGBc1GXUd/FiqivvGHPW/6g7rxi
 ZIrXs+Fqm/5KP9mssNONfyz5XEvbcUTD1CbeqX9eyVbiYZbLp1oWSgtogiRW9ya+
 HR7t0Dt/UFzFWbilb6EZff/Hdr1NZBZLdrfpvVDoMf5tR9J0BIOyjddTu89g/FIO
 KcfJ5yyjJBU=
 =+HAB
 -----END PGP SIGNATURE-----

Merge tags 'objtool-urgent-2021-06-28' and 'objtool-core-2021-06-28' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull objtool fix and updates from Ingo Molnar:
 "An ELF format fix for a section flags mismatch bug that breaks kernel
  tooling such as kpatch-build.

  The biggest change in this cycle is the new code to handle and rewrite
  variable sized jump labels - which results in slightly tighter code
  generation in hot paths, through the use of short(er) NOPs.

  Also a number of cleanups and fixes, and a change to the generic
  include/linux/compiler.h to handle a s390 GCC quirk"

* tag 'objtool-urgent-2021-06-28' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  objtool: Don't make .altinstructions writable

* tag 'objtool-core-2021-06-28' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  objtool: Improve reloc hash size guestimate
  instrumentation.h: Avoid using inline asm operand modifiers
  compiler.h: Avoid using inline asm operand modifiers
  kbuild: Fix objtool dependency for 'OBJECT_FILES_NON_STANDARD_<obj> := n'
  objtool: Reflow handle_jump_alt()
  jump_label/x86: Remove unused JUMP_LABEL_NOP_SIZE
  jump_label, x86: Allow short NOPs
  objtool: Provide stats for jump_labels
  objtool: Rewrite jump_label instructions
  objtool: Decode jump_entry::key addend
  jump_label, x86: Emit short JMP
  jump_label: Free jump_entry::key bit1 for build use
  jump_label, x86: Add variable length patching support
  jump_label, x86: Introduce jump_entry_size()
  jump_label, x86: Improve error when we fail expected text
  jump_label, x86: Factor out the __jump_table generation
  jump_label, x86: Strip ASM jump_label support
  x86, objtool: Dont exclude arch/x86/realmode/
  objtool: Rewrite hashtable sizing
2021-06-28 11:35:55 -07:00
Peter Zijlstra d33b9035e1 objtool: Improve reloc hash size guestimate
Nathan reported that LLVM ThinLTO builds have a performance regression
with commit 25cf0d8aa2 ("objtool: Rewrite hashtable sizing"). Sami
was quick to note that this is due to their use of -ffunction-sections.

As a result the .text section is small and basing the number of relocs
off of that no longer works. Instead have read_sections() compute the
sum of all SHF_EXECINSTR sections and use that.

Fixes: 25cf0d8aa2 ("objtool: Rewrite hashtable sizing")
Reported-by: Nathan Chancellor <nathan@kernel.org>
Debugged-by: Sami Tolvanen <samitolvanen@google.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Tested-by: Nathan Chancellor <nathan@kernel.org>
Link: https://lkml.kernel.org/r/YMJpGLuGNsGtA5JJ@hirez.programming.kicks-ass.net
2021-06-14 14:05:36 +02:00
Peter Zijlstra 584fd3b318 objtool: Fix .symtab_shndx handling for elf_create_undef_symbol()
When an ELF object uses extended symbol section indexes (IOW it has a
.symtab_shndx section), these must be kept in sync with the regular
symbol table (.symtab).

So for every new symbol we emit, make sure to also emit a
.symtab_shndx value to keep the arrays of equal size.

Note: since we're writing an UNDEF symbol, most GElf_Sym fields will
be 0 and we can repurpose one (st_size) to host the 0 for the xshndx
value.

Fixes: 2f2f7e47f0 ("objtool: Add elf_create_undef_symbol()")
Reported-by: Nick Desaulniers <ndesaulniers@google.com>
Suggested-by: Fangrui Song <maskray@google.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Tested-by: Nick Desaulniers <ndesaulniers@google.com>
Link: https://lkml.kernel.org/r/YL3q1qFO9QIRL/BA@hirez.programming.kicks-ass.net
2021-06-10 10:08:24 +02:00
Vasily Gorbik 46c7405df7 objtool: Fix elf_create_undef_symbol() endianness
Currently x86 cross-compilation fails on big endian system with:

  x86_64-cross-ld: init/main.o: invalid string offset 488112128 >= 6229 for section `.strtab'

Mark new ELF data in elf_create_undef_symbol() as symbol, so that libelf
does endianness handling correctly.

Fixes: 2f2f7e47f0 ("objtool: Add elf_create_undef_symbol()")
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: https://lore.kernel.org/r/patch-1.thread-6c9df9.git-d39264656387.your-ad-here.call-01620841104-ext-2554@work.hours
2021-05-12 21:16:53 +02:00
Peter Zijlstra 25cf0d8aa2 objtool: Rewrite hashtable sizing
Currently objtool has 5 hashtables and sizes them 16 or 20 bits
depending on the --vmlinux argument.

However, a single side doesn't really work well for the 5 tables,
which among them, cover 3 different uses. Also, while vmlinux is
larger, there is still a very wide difference between a defconfig and
allyesconfig build, which again isn't optimally covered by a single
size.

Another aspect is the cost of elf_hash_init(), which for large tables
dominates the runtime for small input files. It turns out that all it
does it assign NULL, something that is required when using malloc().
However, when we allocate memory using mmap(), we're guaranteed to get
zero filled pages.

Therefore, rewrite the whole thing to:

 1) use more dynamic sized tables, depending on the input file,
 2) avoid the need for elf_hash_init() entirely by using mmap().

This speeds up a regular kernel build (100s to 98s for
x86_64-defconfig), and potentially dramatically speeds up vmlinux
processing.

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Link: https://lore.kernel.org/r/20210506194157.452881700@infradead.org
2021-05-12 14:54:50 +02:00
Peter Zijlstra 2f2f7e47f0 objtool: Add elf_create_undef_symbol()
Allow objtool to create undefined symbols; this allows creating
relocations to symbols not currently in the symbol table.

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Borislav Petkov <bp@suse.de>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Reviewed-by: Miroslav Benes <mbenes@suse.cz>
Link: https://lkml.kernel.org/r/20210326151300.064743095@infradead.org
2021-04-02 12:45:05 +02:00
Peter Zijlstra 9a7827b778 objtool: Extract elf_symbol_add()
Create a common helper to add symbols.

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Borislav Petkov <bp@suse.de>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Reviewed-by: Miroslav Benes <mbenes@suse.cz>
Link: https://lkml.kernel.org/r/20210326151300.003468981@infradead.org
2021-04-02 12:45:01 +02:00
Peter Zijlstra 417a4dc91e objtool: Extract elf_strtab_concat()
Create a common helper to append strings to a strtab.

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Borislav Petkov <bp@suse.de>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Reviewed-by: Miroslav Benes <mbenes@suse.cz>
Link: https://lkml.kernel.org/r/20210326151259.941474004@infradead.org
2021-04-02 12:44:56 +02:00
Peter Zijlstra d0c5c4cc73 objtool: Create reloc sections implicitly
Have elf_add_reloc() create the relocation section implicitly.

Suggested-by: Josh Poimboeuf <jpoimboe@redhat.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Borislav Petkov <bp@suse.de>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Reviewed-by: Miroslav Benes <mbenes@suse.cz>
Link: https://lkml.kernel.org/r/20210326151259.880174448@infradead.org
2021-04-02 12:44:37 +02:00
Peter Zijlstra ef47cc01cb objtool: Add elf_create_reloc() helper
We have 4 instances of adding a relocation. Create a common helper
to avoid growing even more.

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Borislav Petkov <bp@suse.de>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Reviewed-by: Miroslav Benes <mbenes@suse.cz>
Link: https://lkml.kernel.org/r/20210326151259.817438847@infradead.org
2021-04-02 12:44:18 +02:00
Peter Zijlstra 3a647607b5 objtool: Rework the elf_rebuild_reloc_section() logic
Instead of manually calling elf_rebuild_reloc_section() on sections
we've called elf_add_reloc() on, have elf_write() DTRT.

This makes it easier to add random relocations in places without
carefully tracking when we're done and need to flush what section.

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Borislav Petkov <bp@suse.de>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Reviewed-by: Miroslav Benes <mbenes@suse.cz>
Link: https://lkml.kernel.org/r/20210326151259.754213408@infradead.org
2021-04-02 12:43:32 +02:00
Linus Torvalds a56ff24efb objtool updates:
- Make objtool work for big-endian cross compiles
 
  - Make stack tracking via stack pointer memory operations match push/pop
    semantics to prepare for architectures w/o PUSH/POP instructions.
 
  - Add support for analyzing alternatives
 
  - Improve retpoline detection and handling
 
  - Improve assembly code coverage on x86
 
  - Provide support for inlined stack switching
 -----BEGIN PGP SIGNATURE-----
 
 iQJHBAABCgAxFiEEQp8+kY+LLUocC4bMphj1TA10mKEFAmA1FUcTHHRnbHhAbGlu
 dXRyb25peC5kZQAKCRCmGPVMDXSYoe+0D/9ytW3AfQUOGlVHVPTwCAd2LSCL2kQR
 zrUAyUEwEXDuZi2vOcmgndr9AToszdBnAlxSOStJYE1/ia/ptbYjj9eFOWkCwPw2
 R0DSjTHh+Ui2yPjcbYvOcMphc7DTT1ssMvRWzw0I3fjfJaYBJjNx1qdseN2yhFrL
 BNhdh4B4StEfCbNBMhnzKTZNM1yXNN93ojot9suxnqPIAV6ruc5SUrd9Pmii2odX
 gRHQthGSPMR9nJYWrT2QzbDrM2DWkKIGUol0Xr1LTFYWNFsK3sTQkFiMevTP5Msw
 qO01lw4IKCMKMonaE0t/vxFBz5vhIyivxLQMI3LBixmf2dbE9UbZqW0ONPYoZJgf
 MrYyz4Tdv2u/MklTPM263cbTsdtmGEuW2iVRqaDDWP/Py1A187bUaVkw8p/9O/9V
 CBl8dMF3ag1FquxnsyHDowHKu8DaIZyeBHu69aNfAlcOrtn8ZtY4MwQbQkL9cNYe
 ywLEmCm8zdYNrXlVOuMX/0AAWnSpqCgDYUmKhOLW4W1r4ewNpAUCmvIL8cpLtko0
 FDbMTdKU2pd5SQv5YX6Bvvra483DvP9rNAuQGHpxZ7ubSlj8cFOT9UmjuuOb4fxQ
 EFj8JrF9KEN5sxGUu4tjg0D0Ee3wDdSTGs0cUN5FBMXelQOM7U4n4Y7n/Pas/LMa
 B5TVW3JiDcMcPg==
 =0AHf
 -----END PGP SIGNATURE-----

Merge tag 'objtool-core-2021-02-23' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull objtool updates from Thomas Gleixner:

 - Make objtool work for big-endian cross compiles

 - Make stack tracking via stack pointer memory operations match
   push/pop semantics to prepare for architectures w/o PUSH/POP
   instructions.

 - Add support for analyzing alternatives

 - Improve retpoline detection and handling

 - Improve assembly code coverage on x86

 - Provide support for inlined stack switching

* tag 'objtool-core-2021-02-23' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (33 commits)
  objtool: Support stack-swizzle
  objtool,x86: Additionally decode: mov %rsp, (%reg)
  x86/unwind/orc: Change REG_SP_INDIRECT
  x86/power: Support objtool validation in hibernate_asm_64.S
  x86/power: Move restore_registers() to top of the file
  x86/power: Annotate indirect branches as safe
  x86/acpi: Support objtool validation in wakeup_64.S
  x86/acpi: Annotate indirect branch as safe
  x86/ftrace: Support objtool vmlinux.o validation in ftrace_64.S
  x86/xen/pvh: Annotate indirect branch as safe
  x86/xen: Support objtool vmlinux.o validation in xen-head.S
  x86/xen: Support objtool validation in xen-asm.S
  objtool: Add xen_start_kernel() to noreturn list
  objtool: Combine UNWIND_HINT_RET_OFFSET and UNWIND_HINT_FUNC
  objtool: Add asm version of STACK_FRAME_NON_STANDARD
  objtool: Assume only ELF functions do sibling calls
  x86/ftrace: Add UNWIND_HINT_FUNC annotation for ftrace_stub
  objtool: Support retpoline jump detection for vmlinux.o
  objtool: Fix ".cold" section suffix check for newer versions of GCC
  objtool: Fix retpoline detection in asm code
  ...
2021-02-23 09:56:13 -08:00
Peter Zijlstra 2d24dd5798 rbtree: Add generic add and find helpers
I've always been bothered by the endless (fragile) boilerplate for
rbtree, and I recently wrote some rbtree helpers for objtool and
figured I should lift them into the kernel and use them more widely.

Provide:

partial-order; less() based:
 - rb_add(): add a new entry to the rbtree
 - rb_add_cached(): like rb_add(), but for a rb_root_cached

total-order; cmp() based:
 - rb_find(): find an entry in an rbtree
 - rb_find_add(): find an entry, and add if not found

 - rb_find_first(): find the first (leftmost) matching entry
 - rb_next_match(): continue from rb_find_first()
 - rb_for_each(): iterate a sub-tree using the previous two

Inlining and constant propagation should see the compiler inline the
whole thing, including the various compare functions.

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Reviewed-by: Michel Lespinasse <walken@google.com>
Acked-by: Davidlohr Bueso <dbueso@suse.de>
2021-02-17 14:07:31 +01:00
Josh Poimboeuf 1d489151e9 objtool: Don't fail on missing symbol table
Thanks to a recent binutils change which doesn't generate unused
symbols, it's now possible for thunk_64.o be completely empty without
CONFIG_PREEMPTION: no text, no data, no symbols.

We could edit the Makefile to only build that file when
CONFIG_PREEMPTION is enabled, but that will likely create confusion
if/when the thunks end up getting used by some other code again.

Just ignore it and move on.

Reported-by: Nathan Chancellor <natechancellor@gmail.com>
Reviewed-by: Nathan Chancellor <natechancellor@gmail.com>
Reviewed-by: Miroslav Benes <mbenes@suse.cz>
Tested-by: Nathan Chancellor <natechancellor@gmail.com>
Link: https://github.com/ClangBuiltLinux/linux/issues/1254
Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2021-01-21 15:49:58 -06:00
Vasily Gorbik 7786032e52 objtool: Rework header include paths
Currently objtool headers are being included either by their base name
or included via ../ from a parent directory. In case of a base name usage:

 #include "warn.h"
 #include "arch_elf.h"

it does not make it apparent from which directory the file comes from.
To make it slightly better, and actually to avoid name clashes some arch
specific files have "arch_" suffix. And files from an arch folder have
to revert to including via ../ e.g:
 #include "../../elf.h"

With additional architectures support and the code base growth there is
a need for clearer headers naming scheme for multiple reasons:
1. to make it instantly obvious where these files come from (objtool
   itself / objtool arch|generic folders / some other external files),
2. to avoid name clashes of objtool arch specific headers, potential
   obtool arch generic headers and the system header files (there is
   /usr/include/elf.h already),
3. to avoid ../ includes and improve code readability.
4. to give a warm fuzzy feeling to developers who are mostly kernel
   developers and are accustomed to linux kernel headers arranging
   scheme.

Doesn't this make it instantly obvious where are these files come from?

 #include <objtool/warn.h>
 #include <arch/elf.h>

And doesn't it look nicer to avoid ugly ../ includes? Which also
guarantees this is elf.h from the objtool and not /usr/include/elf.h.

 #include <objtool/elf.h>

This patch defines and implements new objtool headers arranging
scheme. Which is:
- all generic headers go to include/objtool (similar to include/linux)
- all arch headers go to arch/$(SRCARCH)/include/arch (to get arch
  prefix). This is similar to linux arch specific "asm/*" headers but we
  are not abusing "asm" name and calling it what it is. This also helps
  to prevent name clashes (arch is not used in system headers or kernel
  exports).

To bring objtool to this state the following things are done:
1. current top level tools/objtool/ headers are moved into
   include/objtool/ subdirectory,
2. arch specific headers, currently only arch/x86/include/ are moved into
   arch/x86/include/arch/ and were stripped of "arch_" suffix,
3. new -I$(srctree)/tools/objtool/include include path to make
   includes like <objtool/warn.h> possible,
4. rewriting file includes,
5. make git not to ignore include/objtool/ subdirectory.

Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Acked-by: Masami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2021-01-13 18:13:14 -06:00
Martin Schwidefsky a1a664ece5 objtool: Fix reloc generation on big endian cross-compiles
Relocations generated in elf_rebuild_rel[a]_reloc_section() are broken
if objtool is built and run on a big endian system.

The following errors pop up during x86 cross-compilation:

  x86_64-9.1.0-ld: fs/efivarfs/inode.o: bad reloc symbol index (0x2000000 >= 0x22) for offset 0 in section `.orc_unwind_ip'
  x86_64-9.1.0-ld: final link failed: bad value

Convert those functions to use gelf_update_rel[a](), similar to what
elf_write_reloc() does.

Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Co-developed-by: Vasily Gorbik <gor@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Acked-by: Masami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2021-01-13 18:13:12 -06:00
Josh Poimboeuf a2e38dffcd objtool: Don't add empty symbols to the rbtree
Building with the Clang assembler shows the following warning:

  arch/x86/kernel/ftrace_64.o: warning: objtool: missing symbol for insn at offset 0x16

The Clang assembler strips section symbols.  That ends up giving
objtool's find_func_containing() much more test coverage than normal.
Turns out, find_func_containing() doesn't work so well for overlapping
symbols:

     2: 000000000000000e     0 NOTYPE  LOCAL  DEFAULT    2 fgraph_trace
     3: 000000000000000f     0 NOTYPE  LOCAL  DEFAULT    2 trace
     4: 0000000000000000   165 FUNC    GLOBAL DEFAULT    2 __fentry__
     5: 000000000000000e     0 NOTYPE  GLOBAL DEFAULT    2 ftrace_stub

The zero-length NOTYPE symbols are inside __fentry__(), confusing the
rbtree search for any __fentry__() offset coming after a NOTYPE.

Try to avoid this problem by not adding zero-length symbols to the
rbtree.  They're rare and aren't needed in the rbtree anyway.

One caveat, this actually might not end up being the right fix.
Non-empty overlapping symbols, if they exist, could have the same
problem.  But that would need bigger changes, let's see if we can get
away with the easy fix for now.

Reported-by: Arnd Bergmann <arnd@kernel.org>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2021-01-13 16:56:37 -06:00
Josh Poimboeuf 44f6a7c075 objtool: Fix seg fault with Clang non-section symbols
The Clang assembler likes to strip section symbols, which means objtool
can't reference some text code by its section.  This confuses objtool
greatly, causing it to seg fault.

The fix is similar to what was done before, for ORC reloc generation:

  e81e072443 ("objtool: Support Clang non-section symbols in ORC generation")

Factor out that code into a common helper and use it for static call
reloc generation as well.

Reported-by: Arnd Bergmann <arnd@kernel.org>
Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Nick Desaulniers <ndesaulniers@google.com>
Reviewed-by: Miroslav Benes <mbenes@suse.cz>
Link: https://github.com/ClangBuiltLinux/linux/issues/1207
Link: https://lkml.kernel.org/r/ba6b6c0f0dd5acbba66e403955a967d9fdd1726a.1607983452.git.jpoimboe@redhat.com
2020-12-16 14:35:46 +01:00
Josh Poimboeuf 1e7e478838 x86/static_call: Add inline static call implementation for x86-64
Add the inline static call implementation for x86-64. The generated code
is identical to the out-of-line case, except we move the trampoline into
it's own section.

Objtool uses the trampoline naming convention to detect all the call
sites. It then annotates those call sites in the .static_call_sites
section.

During boot (and module init), the call sites are patched to call
directly into the destination function.  The temporary trampoline is
then no longer used.

[peterz: merged trampolines, put trampoline in section]

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Link: https://lore.kernel.org/r/20200818135804.864271425@infradead.org
2020-09-01 09:58:05 +02:00
Peter Zijlstra d832c0051f Merge branch 'objtool/urgent' into objtool/core
Conflicts:
	tools/objtool/elf.c
	tools/objtool/elf.h
	tools/objtool/orc_gen.c
	tools/objtool/check.c

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
2020-06-18 17:55:29 +02:00
Peter Zijlstra fdabdd0b05 objtool: Provide elf_write_{insn,reloc}()
This provides infrastructure to rewrite instructions; this is
immediately useful for helping out with KCOV-vs-noinstr, but will
also come in handy for a bunch of variable sized jump-label patches
that are still on ice.

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
2020-06-18 17:36:33 +02:00
Peter Zijlstra 2b10be23ac objtool: Clean up elf_write() condition
With there being multiple ways to change the ELF data, let's more
concisely track modification.

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
2020-06-18 17:36:33 +02:00
Matt Helsley fb414783b6 objtool: Add support for relocations without addends
Currently objtool only collects information about relocations with
addends. In recordmcount, which we are about to merge into objtool,
some supported architectures do not use rela relocations.

Signed-off-by: Matt Helsley <mhelsley@vmware.com>
Reviewed-by: Julien Thierry <jthierry@redhat.com>
Reviewed-by: Kamalesh Babulal <kamalesh@linux.vnet.ibm.com>
Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2020-06-02 15:37:04 -05:00
Matt Helsley f197422263 objtool: Rename rela to reloc
Before supporting additional relocation types rename the relevant
types and functions from "rela" to "reloc". This work be done with
the following regex:

  sed -e 's/struct rela/struct reloc/g' \
      -e 's/\([_\*]\)rela\(s\{0,1\}\)/\1reloc\2/g' \
      -e 's/tmprela\(s\{0,1\}\)/tmpreloc\1/g' \
      -e 's/relasec/relocsec/g' \
      -e 's/rela_list/reloc_list/g' \
      -e 's/rela_hash/reloc_hash/g' \
      -e 's/add_rela/add_reloc/g' \
      -e 's/rela->/reloc->/g' \
      -e '/rela[,\.]/{ s/\([^\.>]\)rela\([\.,]\)/\1reloc\2/g ; }' \
      -e 's/rela =/reloc =/g' \
      -e 's/relas =/relocs =/g' \
      -e 's/relas\[/relocs[/g' \
      -e 's/relaname =/relocname =/g' \
      -e 's/= rela\;/= reloc\;/g' \
      -e 's/= relas\;/= relocs\;/g' \
      -e 's/= relaname\;/= relocname\;/g' \
      -e 's/, rela)/, reloc)/g' \
      -e 's/\([ @]\)rela\([ "]\)/\1reloc\2/g' \
      -e 's/ rela$/ reloc/g' \
      -e 's/, relaname/, relocname/g' \
      -e 's/sec->rela/sec->reloc/g' \
      -e 's/(\(!\{0,1\}\)rela/(\1reloc/g' \
      -i \
      arch.h \
      arch/x86/decode.c  \
      check.c \
      check.h \
      elf.c \
      elf.h \
      orc_gen.c \
      special.c

Notable exceptions which complicate the regex include gelf_*
library calls and standard/expected section names which still use
"rela" because they encode the type of relocation expected. Also, keep
"rela" in the struct because it encodes a specific type of relocation
we currently expect.

It will eventually turn into a member of an anonymous union when a
susequent patch adds implicit addend, or "rel", relocation support.

Signed-off-by: Matt Helsley <mhelsley@vmware.com>
Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2020-06-01 09:40:58 -05:00
Sami Tolvanen 1e968bf5ca objtool: Use sh_info to find the base for .rela sections
ELF doesn't require .rela section names to match the base section. Use
the section index in sh_info to find the section instead of looking it
up by name.

LLD, for example, generates a .rela section that doesn't match the base
section name when we merge sections in a linker script for a binary
compiled with -ffunction-sections.

Signed-off-by: Sami Tolvanen <samitolvanen@google.com>
Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
Reviewed-by: Kees Cook <keescook@chromium.org>
2020-05-28 11:06:05 -05:00
Kristen Carlson Accardi e000acc145 objtool: Do not assume order of parent/child functions
If a .cold function is examined prior to it's parent, the link
to the parent/child function can be overwritten when the parent
is examined. Only update pfunc and cfunc if they were previously
nil to prevent this from happening.

This fixes an issue seen when compiling with -ffunction-sections.

Signed-off-by: Kristen Carlson Accardi <kristen@linux.intel.com>
Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2020-05-28 11:06:05 -05:00
Sami Tolvanen 28fe1d7bf8 objtool: use gelf_getsymshndx to handle >64k sections
Currently, objtool fails to load the correct section for symbols when
the index is greater than SHN_LORESERVE. Use gelf_getsymshndx instead
of gelf_getsym to handle >64k sections.

Signed-off-by: Sami Tolvanen <samitolvanen@google.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Kees Cook <keescook@chromium.org>
Link: https://lkml.kernel.org/r/20200421220843.188260-2-samitolvanen@google.com
2020-05-15 10:35:13 +02:00
Miroslav Benes b490f45362 objtool: Move the IRET hack into the arch decoder
Quoting Julien:

  "And the other suggestion is my other email was that you don't even
  need to add INSN_EXCEPTION_RETURN. You can keep IRET as
  INSN_CONTEXT_SWITCH by default and x86 decoder lookups the symbol
  conaining an iret. If it's a function symbol, it can just set the type
  to INSN_OTHER so that it caries on to the next instruction after
  having handled the stack_op."

Suggested-by: Julien Thierry <jthierry@redhat.com>
Signed-off-by: Miroslav Benes <mbenes@suse.cz>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Miroslav Benes <mbenes@suse.cz>
Acked-by: Josh Poimboeuf <jpoimboe@redhat.com>
Link: https://lkml.kernel.org/r/20200428191659.913283807@infradead.org
2020-04-30 20:14:33 +02:00
Ingo Molnar bc359ff2f6 objtool: Rename elf_read() to elf_open_read()
'struct elf *' handling is an open/close paradigm, make sure the naming
matches that:

   elf_open_read()
   elf_write()
   elf_close()

Acked-by: Josh Poimboeuf <jpoimboe@redhat.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Sami Tolvanen <samitolvanen@google.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/r/20200422103205.61900-3-mingo@kernel.org
2020-04-23 08:34:18 +02:00
Ingo Molnar 894e48cada objtool: Constify 'struct elf *' parameters
In preparation to parallelize certain parts of objtool, map out which uses
of various data structures are read-only vs. read-write.

As a first step constify 'struct elf' pointer passing, most of the secondary
uses of it in find_symbol_*() methods are read-only.

Also, while at it, better group the 'struct elf' handling methods in elf.h.

Acked-by: Josh Poimboeuf <jpoimboe@redhat.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Sami Tolvanen <samitolvanen@google.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/r/20200422103205.61900-2-mingo@kernel.org
2020-04-23 08:34:18 +02:00
Peter Zijlstra 34f7c96d96 objtool: Optimize !vmlinux.o again
When doing kbuild tests to see if the objtool changes affected those I
found that there was a measurable regression:

          pre		  post

  real    1m13.594        1m16.488s
  user    34m58.246s      35m23.947s
  sys     4m0.393s        4m27.312s

Perf showed that for small files the increased hash-table sizes were a
measurable difference. Since we already have -l "vmlinux" to
distinguish between the modes, make it also use a smaller portion of
the hash-tables.

This flips it into a small win:

  real    1m14.143s
  user    34m49.292s
  sys     3m44.746s

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Miroslav Benes <mbenes@suse.cz>
Reviewed-by: Alexandre Chartre <alexandre.chartre@oracle.com>
Acked-by: Josh Poimboeuf <jpoimboe@redhat.com>
Link: https://lkml.kernel.org/r/20200416115119.167588731@infradead.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
2020-04-22 10:53:50 +02:00