lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <20251119143247.3944213-1-alexandre.chartre@oracle.com>
Date: Wed, 19 Nov 2025 15:32:17 +0100
From: Alexandre Chartre <alexandre.chartre@...cle.com>
To: linux-kernel@...r.kernel.org, mingo@...nel.org, jpoimboe@...nel.org,
        peterz@...radead.org, david.laight.linux@...il.com
Cc: alexandre.chartre@...cle.com
Subject: [PATCH v5 00/30] objtool: Function validation tracing

Hi,

These patches change objtool to disassemble code with libopcodes instead
of running objdump. You will find below:

- Changes: list of changes made in this version
- Overview: overview of the changes
- Notes: description of some particular behavior
- Examples: output examples

Patches are now based on tip/master.

I am deferring the following changes to future patches:
- Josh: convert --disas option to subcommand
- David: provide branch distance for small branches

Thanks,

alex.

-----

Changes:
========

V5: 
---
- patches are now based on tip/master
- remove the resolution of direct/PV calls
  (added in V4 but this needs more work)
- Josh: fix rname
- Josh: change names for jump tables and exception tables
- Josh: display header line for single-line alternatives
- Josh: make NOP<n> lowercase
- Josh: fix alternatives order
- Josh: trim trailing NOPs
- David: indicate the number of trailing NOPs (nop*<n>)
- David: provide compact output for alternatives disassembly.
  The compact output is now the default, and there is a --wide
  option to provide a wide output where alternatives are displayed
  side-by-side.

V4:
---
This version fixes a build issue when disassembly is not available. Compared
with V3, this is addresses by changes in patch 14 (objtool: Improve tracing
of alternative instructions). Other patches are similar to V3.

V3:
---
This version addresses comments from Josh and Peter, in particular:

- Josh: replace ERROR in disas_context_create with WARN
- Josh: do not change offstr() outside the disassembler
- Josh: duplicated "falls through to next function" warning
- Josh: validate_symbol() has extra newline before return
- Josh: "make -s" should be completely silent
- Josh: instructions with unwinding state changes are printing twice
- Josh: explain TRACE_INSN(insn, NULL): this prints an instruction with no
  	additional message.

- Peter: display alternative on a single line
- Peter: display nop-like instruction as NOP<n>
- Peter: in alternative show differences between jmp.d8 and jmp.d32 (jmp/jmpq is used now)
- Peter: show alternative feature name and flags
- Peter: alternative jumps to altinstr_aux - see NOTE below:
         Disassembly can show default alternative jumping to .altinstr_aux
- Peter: some jump label target seems wrong (jmp +0) - NOTE below:
         Disassembly can show alternative jumping to the next instruction

Other improvements:

- An alternatives is displayed on single line if each alternative has a
  single instruction. Otherwise alternatives are dispayed side-by-side,
  with one column for each lternative. XXX option?

- Each alternative of a group alternative is displayed with its feature
  name and flags: <flags><feature-name>

  <flags> is made of the following characters:

    '!' : ALT_FLAG_NOT
    '+' : ALT_FLAG_DIRECT_CALL
    '?' : unknown flag (i.e. any other flags)

- A jump table is displayed the same way as an alternative, with the default
  branch (or not) instruction, and the corresponding substitute instruction.
  It is identified with the "JUMP" name.

- An exception table is displayed the same way as an alternative, with the
  default instruction (which can cause an exception), and a "resume at <desc>"
  string which indicates where the execution resumes if there is an exception.
  It is identified with the "EXCEPTION" name.

- An exception table can be present for an instruction which also has an
  alternative. In that case, the exception table is displayed similarly
  as the different group alternatives for this instruction.

- Print the destination name of pv_ops calls  when we can figure out if
  XENPV mode is used or not. If the PV mode can't be predicted then print
  the default pv_ops destination as a destination example. **REMOVED IN V5**

- If a group alternative is a direct call then print the corresponding
  pv_ops call. **REMOVED IN V5**


Overview:
=========

This provides the following changes to objtool.

- Disassemble code with libopcodes instead of running objdump

  objtool executes the objdump command to disassemble code. In particular,
  if objtool fails to validate a function then it will use objdump to
  disassemble the entire file which is not very helpful when processing
  a large file (like vmlinux.o).

  Using libopcodes provides more control about the disassembly scope and
  output, and it is possible to disassemble a single instruction or
  a single function. Now when objtool fails to validate a function it
  will disassemble that single function instead of disassembling the
  entire file.

- Add the --trace <function> option to trace function validation

  Figuring out why a function validation has failed can be difficult because
  objtool checks all code flows (including alternatives) and maintains
  instructions states (in particular call frame information).

  The trace option allows to follow the function validation done by objtool
  instruction per instruction, see what objtool is doing and get function
  validation information. An output example is shown below.

- Add the --disas <function> option to disassemble functions

  Disassembly is done using libopcodes and it will show the different code
  alternatives.

Note: some changes are architecture specific (x86, powerpc, loongarch). Any
feedback about the behavior on powerpc and loongarch is welcome.


Notes:
======

Disassembly can show default alternative jumping to .altinstr_aux
-----------------------------------------------------------------
Disassembly can show a default alternative jumping to .altinstr_aux. This
happens when the _static_cpu_has() function is used. Its default code
jumps to .altinstr_aux where a test sequence is executed (test; jnz; jmp).

At runtime, this sequence is not used because the _static_cpu_has() 
an alternative with the X86_FEATURE_ALWAYS feature. 


  debc:  perf_get_x86_pmu_capability+0xc      jmpq   0xdec1 <.altinstr_aux+0xfc> | NOP5  (X86_FEATURE_HYBRID_CPU) | jmpq   0x61a <perf_get_x86_pmu_capability+0x37>  (X86_FEATURE_ALWAYS)   # <alternative.debc>
  dec1:  perf_get_x86_pmu_capability+0x11     ud2                                                       


Disassembly can show alternative jumping to the next instruction
----------------------------------------------------------------

The disassembly can show jump tables with an alternative which jumps
to the next instruction.

For example:

def9:  perf_get_x86_pmu_capability+0x49    NOP2 | jmp    defb <perf_get_x86_pmu_capability+0x4b>  (JUMP)   # <alternative.def9>
defb:  perf_get_x86_pmu_capability+0x4b	   mov    0x0(%rip),%rdi        # 0xdf02 <x86_pmu+0xd8>      

This disassembly is correct. These instructions come from:

        cap->num_counters_gp = x86_pmu_num_counters(NULL)):

which will end up executing this statement:

        if (static_branch_unlikely(&perf_is_hybrid) && NULL)
	        <do something>;

This statement is optimized to do nothing because the condition is
always false. But static_branch_unlikely() is implemented with a jump
table inside an "asm goto" statement, and "asm goto" statements are
not optimized.

So basically the code is optimized like this:

        if (static_branch_unlikely(&perf_is_hybrid))
	        ;

And this translates to the assembly code above.


Examples:
=========

Example 1 (--trace option): Trace the validation of the os_save() function
--------------------------------------------------------------------------

$ ./tools/objtool/objtool --hacks=jump_label --hacks=noinstr --hacks=skylake --ibt --orc --retpoline --rethunk --sls --static-call --uaccess --prefix=16 --link --trace os_xsave -v vmlinux.o
os_xsave: validation begin
 59be0:  os_xsave+0x0                  push   %r12                                          - state: cfa=rsp+16 r12=(cfa-16) stack_size=16 
 59be2:  os_xsave+0x2		       mov    0x0(%rip),%eax        # 0x59be8 <alternatives_patched>
 59be8:  os_xsave+0x8		       push   %rbp                                          - state: cfa=rsp+24 rbp=(cfa-24) stack_size=24 
 59be9:  os_xsave+0x9		       mov    %rdi,%rbp                                          
 59bec:  os_xsave+0xc		       push   %rbx					     - state: cfa=rsp+32 rbx=(cfa-32) stack_size=32 
 59bed:  os_xsave+0xd		       mov    0x8(%rdi),%rbx                                     
 59bf1:  os_xsave+0x11		       mov    %rbx,%r12                                          
 59bf4:  os_xsave+0x14		       shr    $0x20,%r12                                         
 59bf8:  os_xsave+0x18		       test   %eax,%eax                                          
 59bfa:  os_xsave+0x1a		       je     0x59c22 <os_xsave+0x42>                        - jump taken
 59c22:  os_xsave+0x42		       | ud2                                                     
 59c24:  os_xsave+0x44		       | jmp    0x59bfc <os_xsave+0x1c>                      - unconditional jump
 59bfc:  os_xsave+0x1c		       | | xor    %edx,%edx                                      
 59bfe:  os_xsave+0x1e		       | | mov    %rbx,%rsi                                      
 59c01:  os_xsave+0x21		       | | mov    %rbp,%rdi                                      
 59c04:  os_xsave+0x24		       | | callq  0x59c09 <xfd_validate_state>               - call
 59c09:  os_xsave+0x29		       | | mov    %ebx,%eax                                      
 59c0b:  os_xsave+0x2b		       | | mov    %r12d,%edx                                     
 	 			       | | / <alternative.59c0e> X86_FEATURE_XSAVEOPT
  1b29:  .altinstr_replacement+0x1b29  | | | xsaveopt64 0x40(%rbp)                               
 59c13:  os_xsave+0x33		       | | | xor    %ebx,%ebx                                    
 59c15:  os_xsave+0x35		       | | | test   %ebx,%ebx                                    
 59c17:  os_xsave+0x37		       | | | jne    0x59c26 <os_xsave+0x46>                  - jump taken
 59c26:  os_xsave+0x46		       | | | | ud2                                               
 59c28:  os_xsave+0x48		       | | | | pop    %rbx                                   - state: cfa=rsp+24 rbx=<undef> stack_size=24 
 59c29:  os_xsave+0x49		       | | | | pop    %rbp				     - state: cfa=rsp+16 rbp=<undef> stack_size=16 
 59c2a:  os_xsave+0x4a		       | | | | pop    %r12				     - state: cfa=rsp+8 r12=<undef> stack_size=8 
 59c2c:  os_xsave+0x4c		       | | | | jmpq   0x59c31 <__x86_return_thunk>	     - return
 59c17:  os_xsave+0x37		       | | | jne    0x59c26 <os_xsave+0x46>		     - jump not taken
 59c19:  os_xsave+0x39		       | | | pop    %rbx    				     - state: cfa=rsp+24 rbx=<undef> stack_size=24 
 59c1a:  os_xsave+0x3a		       | | | pop    %rbp				     - state: cfa=rsp+16 rbp=<undef> stack_size=16 
 59c1b:  os_xsave+0x3b		       | | | pop    %r12				     - state: cfa=rsp+8 r12=<undef> stack_size=8 
 59c1d:  os_xsave+0x3d		       | | | jmpq   0x59c22 <__x86_return_thunk>	     - return
 	 			       | | \ <alternative.59c0e> X86_FEATURE_XSAVEOPT
				       | | / <alternative.59c0e> X86_FEATURE_XSAVEC
  1b2e:  .altinstr_replacement+0x1b2e  | | | xsavec64 0x40(%rbp)                                 
 59c13:  os_xsave+0x33		       | | | xor    %ebx,%ebx                                - already visited
 	 			       | | \ <alternative.59c0e> X86_FEATURE_XSAVEC
				       | | / <alternative.59c0e> X86_FEATURE_XSAVES
  1b33:  .altinstr_replacement+0x1b33  | | | xsaves64 0x40(%rbp)                                 
 59c13:  os_xsave+0x33		       | | | xor    %ebx,%ebx                                - already visited
 	 			       | | \ <alternative.59c0e> X86_FEATURE_XSAVES
				       | | / <alternative.59c0e> EXCEPTION for instruction at 0x59c0e <os_xsave+0x2e>
 59c15:  os_xsave+0x35		       | | | test   %ebx,%ebx                                - already visited
 	 			       | | \ <alternative.59c0e> EXCEPTION
				       | | / <alternative.59c0e> DEFAULT
 59c0e:  os_xsave+0x2e		       | | xsave64 0x40(%rbp)                                    
 59c13:  os_xsave+0x33		       | | xor    %ebx,%ebx                                  - already visited
 59bfa:  os_xsave+0x1a		       je     0x59c22 <os_xsave+0x42>                        - jump not taken
 59bfc:  os_xsave+0x1c		       xor    %edx,%edx                                      - already visited
os_xsave: validation end


Example 2 (--disas option): Single Instruction Alternatives
-----------------------------------------------------------

Compact Output (default):

Alternatives with single instructions are displayed each on one line,
with the instruction and a description of the alternative.

$ ./tools/objtool/objtool --disas=perf_get_x86_pmu_capability --link vmlinux.o
perf_get_x86_pmu_capability:
  deb0:  perf_get_x86_pmu_capability+0x0     endbr64                                                   
  deb4:  perf_get_x86_pmu_capability+0x4     callq  0xdeb9 <__fentry__>                                
  deb9:  perf_get_x86_pmu_capability+0x9     mov    %rdi,%rdx                                          
  debc:  perf_get_x86_pmu_capability+0xc     <alternative.debc>
  	 				     = jmpq   0xdec1 <.altinstr_aux+0xfc>                 (if DEFAULT)
					     = jmpq   0x622 <perf_get_x86_pmu_capability+0x37>    (if X86_FEATURE_ALWAYS)
					     = nop5                                               (if X86_FEATURE_HYBRID_CPU)
  dec1:  perf_get_x86_pmu_capability+0x11    ud2                                                       
  dec3:  perf_get_x86_pmu_capability+0x13    movq   $0x0,(%rdx)                                        
  deca:  perf_get_x86_pmu_capability+0x1a    movq   $0x0,0x8(%rdx)                                     
  ded2:  perf_get_x86_pmu_capability+0x22    movq   $0x0,0x10(%rdx)                                    
  deda:  perf_get_x86_pmu_capability+0x2a    movq   $0x0,0x18(%rdx)                                    
  dee2:  perf_get_x86_pmu_capability+0x32    jmpq   0xdee7 <__x86_return_thunk>                        
  dee7:  perf_get_x86_pmu_capability+0x37    cmpq   $0x0,0x0(%rip)        # 0xdeef <x86_pmu+0x10>      
  deef:  perf_get_x86_pmu_capability+0x3f    je     0xdec3 <perf_get_x86_pmu_capability+0x13>          
  def1:  perf_get_x86_pmu_capability+0x41    mov    0x0(%rip),%eax        # 0xdef7 <x86_pmu+0x8>       
  def7:  perf_get_x86_pmu_capability+0x47    mov    %eax,(%rdi)                                        
  def9:  perf_get_x86_pmu_capability+0x49    <jump_table.def9>
  	 				     = nop2                                              (if DEFAULT)
					     = jmp    defb <perf_get_x86_pmu_capability+0x4b>    (if JUMP)
  defb:  perf_get_x86_pmu_capability+0x4b    mov    0x0(%rip),%rdi        # 0xdf02 <x86_pmu+0xd8>      
  df02:  perf_get_x86_pmu_capability+0x52    <alternative.df02>
  	 				     = callq  0xdf07 <__sw_hweight64>    (if DEFAULT)
					     = popcnt %rdi,%rax                  (if X86_FEATURE_POPCNT)
  df07:  perf_get_x86_pmu_capability+0x57    mov    %eax,0x4(%rdx)                                     
  df0a:  perf_get_x86_pmu_capability+0x5a    <jump_table.df0a>
  	 				     = nop2                                              (if DEFAULT)
					     = jmp    df0c <perf_get_x86_pmu_capability+0x5c>    (if JUMP)
  df0c:  perf_get_x86_pmu_capability+0x5c    mov    0x0(%rip),%rdi        # 0xdf13 <x86_pmu+0xe0>      
  df13:  perf_get_x86_pmu_capability+0x63    <alternative.df13>
  	 				     = callq  0xdf18 <__sw_hweight64>    (if DEFAULT)
					     = popcnt %rdi,%rax                  (if X86_FEATURE_POPCNT)
  df18:  perf_get_x86_pmu_capability+0x68    mov    %eax,0x8(%rdx)                                     
  df1b:  perf_get_x86_pmu_capability+0x6b    mov    0x0(%rip),%eax        # 0xdf21 <x86_pmu+0xf8>      
  df21:  perf_get_x86_pmu_capability+0x71    mov    %eax,0xc(%rdx)                                     
  df24:  perf_get_x86_pmu_capability+0x74    mov    %eax,0x10(%rdx)                                    
  df27:  perf_get_x86_pmu_capability+0x77    mov    0x0(%rip),%rax        # 0xdf2e <x86_pmu+0x108>     
  df2e:  perf_get_x86_pmu_capability+0x7e    mov    %eax,0x14(%rdx)                                    
  df31:  perf_get_x86_pmu_capability+0x81    mov    0x0(%rip),%eax        # 0xdf37 <x86_pmu+0x110>     
  df37:  perf_get_x86_pmu_capability+0x87    mov    %eax,0x18(%rdx)                                    
  df3a:  perf_get_x86_pmu_capability+0x8a    movzbl 0x0(%rip),%ecx        # 0xdf41 <x86_pmu+0x1d1>     
  df41:  perf_get_x86_pmu_capability+0x91    movzbl 0x1c(%rdx),%eax                                    
  df45:  perf_get_x86_pmu_capability+0x95    shr    %cl                                                
  df47:  perf_get_x86_pmu_capability+0x97    and    $0x1,%ecx                                          
  df4a:  perf_get_x86_pmu_capability+0x9a    and    $0xfffffffe,%eax                                   
  df4d:  perf_get_x86_pmu_capability+0x9d    or     %ecx,%eax                                          
  df4f:  perf_get_x86_pmu_capability+0x9f    mov    %al,0x1c(%rdx)                                     
  df52:  perf_get_x86_pmu_capability+0xa2    jmpq   0xdf57 <__x86_return_thunk>                        


Wide Output (--wide option):

Alternatives with single instructions are displayed side-by-side,
with an header.

$ ./tools/objtool/objtool --disas=perf_get_x86_pmu_capability --wide --link vmlinux.o
perf_get_x86_pmu_capability:
  deb0:  perf_get_x86_pmu_capability+0x0       endbr64                                                   
  deb4:  perf_get_x86_pmu_capability+0x4       callq  0xdeb9 <__fentry__>                                
  deb9:  perf_get_x86_pmu_capability+0x9       mov    %rdi,%rdx                                          
  debc:  perf_get_x86_pmu_capability+0xc     | <alternative.debc>                 | X86_FEATURE_ALWAYS                              | X86_FEATURE_HYBRID_CPU 
  debc:  perf_get_x86_pmu_capability+0xc     | jmpq   0xdec1 <.altinstr_aux+0xfc> | jmpq   0x622 <perf_get_x86_pmu_capability+0x37> | nop5                   
  dec1:  perf_get_x86_pmu_capability+0x11      ud2                                                       
  dec3:  perf_get_x86_pmu_capability+0x13      movq   $0x0,(%rdx)                                        
  deca:  perf_get_x86_pmu_capability+0x1a      movq   $0x0,0x8(%rdx)                                     
  ded2:  perf_get_x86_pmu_capability+0x22      movq   $0x0,0x10(%rdx)                                    
  deda:  perf_get_x86_pmu_capability+0x2a      movq   $0x0,0x18(%rdx)                                    
  dee2:  perf_get_x86_pmu_capability+0x32      jmpq   0xdee7 <__x86_return_thunk>                        
  dee7:  perf_get_x86_pmu_capability+0x37      cmpq   $0x0,0x0(%rip)        # 0xdeef <x86_pmu+0x10>      
  deef:  perf_get_x86_pmu_capability+0x3f      je     0xdec3 <perf_get_x86_pmu_capability+0x13>          
  def1:  perf_get_x86_pmu_capability+0x41      mov    0x0(%rip),%eax        # 0xdef7 <x86_pmu+0x8>       
  def7:  perf_get_x86_pmu_capability+0x47      mov    %eax,(%rdi)                                        
  def9:  perf_get_x86_pmu_capability+0x49    | <jump_table.def9> | JUMP                                           
  def9:  perf_get_x86_pmu_capability+0x49    | nop2              | jmp    defb <perf_get_x86_pmu_capability+0x4b> 
  defb:  perf_get_x86_pmu_capability+0x4b      mov    0x0(%rip),%rdi        # 0xdf02 <x86_pmu+0xd8>      
  df02:  perf_get_x86_pmu_capability+0x52    | <alternative.df02>             | X86_FEATURE_POPCNT 
  df02:  perf_get_x86_pmu_capability+0x52    | callq  0xdf07 <__sw_hweight64> | popcnt %rdi,%rax   
  df07:  perf_get_x86_pmu_capability+0x57      mov    %eax,0x4(%rdx)                                     
  df0a:  perf_get_x86_pmu_capability+0x5a    | <jump_table.df0a> | JUMP                                           
  df0a:  perf_get_x86_pmu_capability+0x5a    | nop2              | jmp    df0c <perf_get_x86_pmu_capability+0x5c> 
  df0c:  perf_get_x86_pmu_capability+0x5c      mov    0x0(%rip),%rdi        # 0xdf13 <x86_pmu+0xe0>      
  df13:  perf_get_x86_pmu_capability+0x63    | <alternative.df13>             | X86_FEATURE_POPCNT 
  df13:  perf_get_x86_pmu_capability+0x63    | callq  0xdf18 <__sw_hweight64> | popcnt %rdi,%rax   
  df18:  perf_get_x86_pmu_capability+0x68      mov    %eax,0x8(%rdx)                                     
  df1b:  perf_get_x86_pmu_capability+0x6b      mov    0x0(%rip),%eax        # 0xdf21 <x86_pmu+0xf8>      
  df21:  perf_get_x86_pmu_capability+0x71      mov    %eax,0xc(%rdx)                                     
  df24:  perf_get_x86_pmu_capability+0x74      mov    %eax,0x10(%rdx)                                    
  df27:  perf_get_x86_pmu_capability+0x77      mov    0x0(%rip),%rax        # 0xdf2e <x86_pmu+0x108>     
  df2e:  perf_get_x86_pmu_capability+0x7e      mov    %eax,0x14(%rdx)                                    
  df31:  perf_get_x86_pmu_capability+0x81      mov    0x0(%rip),%eax        # 0xdf37 <x86_pmu+0x110>     
  df37:  perf_get_x86_pmu_capability+0x87      mov    %eax,0x18(%rdx)                                    
  df3a:  perf_get_x86_pmu_capability+0x8a      movzbl 0x0(%rip),%ecx        # 0xdf41 <x86_pmu+0x1d1>     
  df41:  perf_get_x86_pmu_capability+0x91      movzbl 0x1c(%rdx),%eax                                    
  df45:  perf_get_x86_pmu_capability+0x95      shr    %cl                                                
  df47:  perf_get_x86_pmu_capability+0x97      and    $0x1,%ecx                                          
  df4a:  perf_get_x86_pmu_capability+0x9a      and    $0xfffffffe,%eax                                   
  df4d:  perf_get_x86_pmu_capability+0x9d      or     %ecx,%eax                                          
  df4f:  perf_get_x86_pmu_capability+0x9f      mov    %al,0x1c(%rdx)                                     
  df52:  perf_get_x86_pmu_capability+0xa2      jmpq   0xdf57 <__x86_return_thunk>                        


Example 3 (--disas option): Alternatives with multiple instructions
-------------------------------------------------------------------

Compact Output (default):

Alternatives with multiple instructions are displayed one above the other,
with an header describing the alternative.

$ ./tools/objtool/objtool --disas=__switch_to_asm --link vmlinux.o
__switch_to_asm:
  82c0:  __switch_to_asm+0x0       push   %rbp                                               
  82c1:  __switch_to_asm+0x1	   push   %rbx                                               
  82c2:  __switch_to_asm+0x2	   push   %r12                                               
  82c4:  __switch_to_asm+0x4	   push   %r13                                               
  82c6:  __switch_to_asm+0x6	   push   %r14                                               
  82c8:  __switch_to_asm+0x8	   push   %r15                                               
  82ca:  __switch_to_asm+0xa	   mov    %rsp,0x1670(%rdi)                                  
  82d1:  __switch_to_asm+0x11	   mov    0x1670(%rsi),%rsp                                  
  82d8:  __switch_to_asm+0x18	   mov    0xad8(%rsi),%rbx                                   
  82df:  __switch_to_asm+0x1f	   mov    %rbx,%gs:0x0(%rip)        # 0x82e7 <__stack_chk_guard>
  82e7:  __switch_to_asm+0x27	   <alternative.82e7>
  	 			   = DEFAULT
  82e7:  __switch_to_asm+0x27	   | jmp    0x8312 <__switch_to_asm+0x52>
  82e9:  __switch_to_asm+0x29	   | nop*41
  	 			   |
				   = X86_FEATURE_RSB_CTXSW
  82e7:  __switch_to_asm+0x27	   | mov    $0x10,%r12
  82ee:  __switch_to_asm+0x2e	   | callq  0x82f4 <__switch_to_asm+0x34>
  82f3:  __switch_to_asm+0x33	   | int3   
  82f4:  __switch_to_asm+0x34	   | callq  0x82fa <__switch_to_asm+0x3a>
  82f9:  __switch_to_asm+0x39	   | int3   
  82fa:  __switch_to_asm+0x3a	   | add    $0x10,%rsp
  82fe:  __switch_to_asm+0x3e	   | dec    %r12
  8301:  __switch_to_asm+0x41	   | jne    0x82ee <__switch_to_asm+0x2e>
  8303:  __switch_to_asm+0x43	   | lfence 
  8306:  __switch_to_asm+0x46	   | movq   $0xffffffffffffffff,%gs:0x0(%rip)        # 0x20b <__x86_call_depth>
  	 			   |
				   = !X86_FEATURE_ALWAYS
  82e7:  __switch_to_asm+0x27	   | nop1
  82e8:  __switch_to_asm+0x28	   | nop1
  82e9:  __switch_to_asm+0x29	   | callq  0x82ef <__switch_to_asm+0x2f>
  82ee:  __switch_to_asm+0x2e	   | int3   
  82ef:  __switch_to_asm+0x2f	   | add    $0x8,%rsp
  82f3:  __switch_to_asm+0x33	   | lfence 
  	 			   |
  8312:  __switch_to_asm+0x52	   pop    %r15                                               
  8314:  __switch_to_asm+0x54	   pop    %r14                                               
  8316:  __switch_to_asm+0x56	   pop    %r13                                               
  8318:  __switch_to_asm+0x58	   pop    %r12                                               
  831a:  __switch_to_asm+0x5a	   pop    %rbx                                               
  831b:  __switch_to_asm+0x5b	   pop    %rbp                                               
  831c:  __switch_to_asm+0x5c	   jmpq   0x8321 <__switch_to>                               


Wide Output (--wide option):

Alternatives with multiple instructions are displayed side-by-side, with
an header describing the alternative. The code in the first column is the
default code of the alternative.

$ ./tools/objtool/objtool --disas=__switch_to_asm --wide  --link vmlinux.o
__switch_to_asm:
  82c0:  __switch_to_asm+0x0       push   %rbp                                               
  82c1:  __switch_to_asm+0x1	   push   %rbx                                               
  82c2:  __switch_to_asm+0x2	   push   %r12                                               
  82c4:  __switch_to_asm+0x4	   push   %r13                                               
  82c6:  __switch_to_asm+0x6	   push   %r14                                               
  82c8:  __switch_to_asm+0x8	   push   %r15                                               
  82ca:  __switch_to_asm+0xa	   mov    %rsp,0x1670(%rdi)                                  
  82d1:  __switch_to_asm+0x11	   mov    0x1670(%rsi),%rsp                                  
  82d8:  __switch_to_asm+0x18	   mov    0xad8(%rsi),%rbx                                   
  82df:  __switch_to_asm+0x1f	   mov    %rbx,%gs:0x0(%rip)        # 0x82e7 <__stack_chk_guard>
  82e7:  __switch_to_asm+0x27	 | <alternative.82e7>                   | X86_FEATURE_RSB_CTXSW                                               | !X86_FEATURE_ALWAYS
  82e7:  __switch_to_asm+0x27	 | jmp    0x8312 <__switch_to_asm+0x52> | mov    $0x10,%r12						      | nop1
  82e8:  __switch_to_asm+0x28	 |                                      | 	 							      | nop1
  82e9:  __switch_to_asm+0x29	 | nop*41                               |                                                                     | callq  0x82ef <__switch_to_asm+0x2f>
  82ee:  __switch_to_asm+0x2e	 |                                      | callq  0x82f4 <__switch_to_asm+0x34>                                | int3
  82ef:  __switch_to_asm+0x2f	 |                                      |                                                                     | add    $0x8,%rsp
  82f3:  __switch_to_asm+0x33	 |                                      | int3                                                                | lfence
  82f4:  __switch_to_asm+0x34	 |                                      | callq  0x82fa <__switch_to_asm+0x3a>                                |
  82f9:  __switch_to_asm+0x39	 |                                      | int3                                                                |
  82fa:  __switch_to_asm+0x3a	 |                                      | add    $0x10,%rsp                                                   |
  82fe:  __switch_to_asm+0x3e	 |                                      | dec    %r12                                                         |
  8301:  __switch_to_asm+0x41	 |                                      | jne    0x82ee <__switch_to_asm+0x2e>                                |
  8303:  __switch_to_asm+0x43	 |                                      | lfence                                                              |
  8306:  __switch_to_asm+0x46	 |                                      | movq   $0xffffffffffffffff,%gs:0x0(%rip) # 0x20b <__x86_call_depth> |
  8312:  __switch_to_asm+0x52	   pop    %r15                                               
  8314:  __switch_to_asm+0x54	   pop    %r14                                               
  8316:  __switch_to_asm+0x56	   pop    %r13                                               
  8318:  __switch_to_asm+0x58	   pop    %r12                                               
  831a:  __switch_to_asm+0x5a	   pop    %rbx                                               
  831b:  __switch_to_asm+0x5b	   pop    %rbp                                               
  831c:  __switch_to_asm+0x5c	   jmpq   0x8321 <__switch_to>
  
-----

Alexandre Chartre (30):
  objtool: Move disassembly functions to a separated file
  objtool: Create disassembly context
  objtool: Disassemble code with libopcodes instead of running objdump
  tool build: Remove annoying newline in build output
  objtool: Print symbol during disassembly
  objtool: Store instruction disassembly result
  objtool: Disassemble instruction on warning or backtrace
  objtool: Extract code to validate instruction from the validate branch
    loop
  objtool: Record symbol name max length
  objtool: Add option to trace function validation
  objtool: Trace instruction state changes during function validation
  objtool: Improve register reporting during function validation
  objtool: Identify the different types of alternatives
  objtool: Add functions to better name alternatives
  objtool: Improve tracing of alternative instructions
  objtool: Do not validate IBT for .return_sites and .call_sites
  objtool: Add the --disas=<function-pattern> action
  objtool: Preserve alternatives order
  objtool: Print headers for alternatives
  objtool: Disassemble group alternatives
  objtool: Print addresses with alternative instructions
  objtool: Disassemble exception table alternatives
  objtool: Disassemble jump table alternatives
  objtool: Fix address references in alternatives
  objtool: Provide access to feature and flags of group alternatives
  objtool: Function to get the name of a CPU feature
  objtool: Improve naming of group alternatives
  objtool: Compact output for alternatives with one instruction
  objtool: Add wide output for disassembly
  objtool: Trim trailing NOPs in alternative

 .../x86/tools/gen-cpu-feature-names-x86.awk   |   33 +
 tools/build/Makefile.feature                  |    4 +-
 tools/objtool/Build                           |    3 +
 tools/objtool/Makefile                        |   24 +
 tools/objtool/arch/loongarch/decode.c         |   23 +
 tools/objtool/arch/loongarch/special.c        |    5 +
 tools/objtool/arch/powerpc/decode.c           |   24 +
 tools/objtool/arch/powerpc/special.c          |    5 +
 tools/objtool/arch/x86/Build                  |    8 +
 tools/objtool/arch/x86/decode.c               |   20 +
 tools/objtool/arch/x86/special.c              |   10 +
 tools/objtool/builtin-check.c                 |    4 +
 tools/objtool/check.c                         |  648 +++++----
 tools/objtool/disas.c                         | 1245 +++++++++++++++++
 tools/objtool/include/objtool/arch.h          |   11 +
 tools/objtool/include/objtool/builtin.h       |    3 +
 tools/objtool/include/objtool/check.h         |   35 +-
 tools/objtool/include/objtool/disas.h         |   81 ++
 tools/objtool/include/objtool/special.h       |    4 +-
 tools/objtool/include/objtool/trace.h         |  141 ++
 tools/objtool/include/objtool/warn.h          |   17 +-
 tools/objtool/special.c                       |    2 +
 tools/objtool/trace.c                         |  203 +++
 23 files changed, 2254 insertions(+), 299 deletions(-)
 create mode 100644 tools/arch/x86/tools/gen-cpu-feature-names-x86.awk
 create mode 100644 tools/objtool/disas.c
 create mode 100644 tools/objtool/include/objtool/disas.h
 create mode 100644 tools/objtool/include/objtool/trace.h
 create mode 100644 tools/objtool/trace.c

-- 
2.43.5


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ