mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [RFC 00/13] objtool: Function validation tracing
@ 2025-06-06 15:34 Alexandre Chartre
  2025-06-06 15:34 ` [RFC 01/13] objtool: Move disassembly functions to a separated file Alexandre Chartre
                   ` (14 more replies)
  0 siblings, 15 replies; 32+ messages in thread
From: Alexandre Chartre @ 2025-06-06 15:34 UTC (permalink / raw)
  To: linux-kernel, mingo, jpoimboe, peterz; +Cc: alexandre.chartre

Hi,

This RFC provides two 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.

Note: some changes are architecture specific (x86, powerpc, loongarch). So far,
I have only tested on x86, and some code might be x86 specific. Any feedback
about the behavior on powerpc and loongarch is welcome.

Thanks,

alex.


-----

Example: Trace the validation of the os_save() function in vmlinux.o

$ ./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
 65c20: os_xsave+0x0  push %r12				- state: cfa=rsp+16 r12=(cfa-16) stack_size=16 
 65c22: os_xsave+0x2  mov 0x0(%rip),%eax # alternatives_patched 
 65c28: os_xsave+0x8  push %rbp 			- state: cfa=rsp+24 rbp=(cfa-24) stack_size=24 
 65c29: os_xsave+0x9  mov %rdi,%rbp 
 65c2c: os_xsave+0xc  push %rbx 			- state: cfa=rsp+32 rbx=(cfa-32) stack_size=32 
 65c2d: os_xsave+0xd  mov 0x8(%rdi),%rbx 
 65c31: os_xsave+0x11 mov %rbx,%r12 
 65c34: os_xsave+0x14 shr $0x20,%r12 
 65c38: os_xsave+0x18 test %eax,%eax 
 65c3a: os_xsave+0x1a je 65c6a <os_xsave+0x4a> 		- jump taken
 65c6a: os_xsave+0x4a | ud2 
 65c6c: os_xsave+0x4c | jmp 65c3c <os_xsave+0x1c> 	- unconditional jump
 65c3c: os_xsave+0x1c | xor %edx,%edx 
 65c3e: os_xsave+0x1e | mov %rbx,%rsi 
 65c41: os_xsave+0x21 | mov %rbp,%rdi 
 65c44: os_xsave+0x24 | callq xfd_validate_state 	- call
 65c49: os_xsave+0x29 | mov %ebx,%eax 
 65c4b: os_xsave+0x2b | mov %r12d,%edx 
 65c4e: os_xsave+0x2e | <alternative.65c4e> alt 1/4 begin
 65c55: os_xsave+0x35 | | test %ebx,%ebx 
 65c57: os_xsave+0x37 | | jne 65c6e <os_xsave+0x4e> 	- jump taken
 65c6e: os_xsave+0x4e | | | ud2 
 65c70: os_xsave+0x50 | | | pop %rbx 			- state: cfa=rsp+24 rbx=<undef> stack_size=24 
 65c71: os_xsave+0x51 | | | pop %rbp 			- state: cfa=rsp+16 rbp=<undef> stack_size=16 
 65c72: os_xsave+0x52 | | | pop %r12 			- state: cfa=rsp+8 r12=<undef> stack_size=8 
 65c74: os_xsave+0x54 | | | xor %eax,%eax 
 65c76: os_xsave+0x56 | | | xor %edx,%edx 
 65c78: os_xsave+0x58 | | | xor %esi,%esi 
 65c7a: os_xsave+0x5a | | | xor %edi,%edi 
 65c7c: os_xsave+0x5c | | | jmpq __x86_return_thunk 	- return
 65c57: os_xsave+0x37 | | jne 65c6e <os_xsave+0x4e> 	- jump not taken
 65c59: os_xsave+0x39 | | pop %rbx 			- state: cfa=rsp+24 rbx=<undef> stack_size=24 
 65c5a: os_xsave+0x3a | | pop %rbp 			- state: cfa=rsp+16 rbp=<undef> stack_size=16 
 65c5b: os_xsave+0x3b | | pop %r12 			- state: cfa=rsp+8 r12=<undef> stack_size=8 
 65c5d: os_xsave+0x3d | | xor %eax,%eax 
 65c5f: os_xsave+0x3f | | xor %edx,%edx 
 65c61: os_xsave+0x41 | | xor %esi,%esi 
 65c63: os_xsave+0x43 | | xor %edi,%edi 
 65c65: os_xsave+0x45 | | jmpq __x86_return_thunk - return
                      | <alternative.65c4e> alt 1/4 end
 65c4e: os_xsave+0x2e | <alternative.65c4e> alt 2/4 begin
 1c3d: .altinstr_replacement+0x1c3d | | xsaves64 0x40(%rbp) 
 65c53: os_xsave+0x33 | | xor %ebx,%ebx 
 65c55: os_xsave+0x35 | | test %ebx,%ebx - already visited
                      | <alternative.65c4e> alt 2/4 end
 65c4e: os_xsave+0x2e | <alternative.65c4e> alt 3/4 begin
 1c38: .altinstr_replacement+0x1c38 | | xsavec64 0x40(%rbp) 
 65c53: os_xsave+0x33 | | xor %ebx,%ebx - already visited
                      | <alternative.65c4e> alt 3/4 end
 65c4e: os_xsave+0x2e | <alternative.65c4e> alt 4/4 begin
 1c33: .altinstr_replacement+0x1c33 | | xsaveopt64 0x40(%rbp) 
 65c53: os_xsave+0x33 | | xor %ebx,%ebx - already visited
                      | <alternative.65c4e> alt 4/4 end
 65c4e: os_xsave+0x2e | <alternative.65c4e> alt default
 65c4e: os_xsave+0x2e | xsave64 0x40(%rbp) 
 65c53: os_xsave+0x33 | xor %ebx,%ebx - already visited
 65c3a: os_xsave+0x1a je 65c6a <os_xsave+0x4a> - jump not taken
 65c3c: os_xsave+0x1c xor %edx,%edx - already visited
os_xsave: validation end

-----

Alexandre Chartre (13):
  objtool: Move disassembly functions to a separated file
  objtool: Create disassembly context
  objtool: Disassemble code with libopcodes instead of running objdump
  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: Improve tracing of alternative instructions
  objtool: Do not validate IBT for .return_sites and .call_sites

 tools/objtool/Build                     |   1 +
 tools/objtool/Makefile                  |   2 +-
 tools/objtool/arch/loongarch/decode.c   |  17 +
 tools/objtool/arch/powerpc/decode.c     |  18 +
 tools/objtool/arch/x86/decode.c         |  15 +
 tools/objtool/builtin-check.c           |   1 +
 tools/objtool/check.c                   | 829 ++++++++++++++++--------
 tools/objtool/disas.c                   | 452 +++++++++++++
 tools/objtool/include/objtool/arch.h    |   7 +
 tools/objtool/include/objtool/builtin.h |   1 +
 tools/objtool/include/objtool/check.h   |  29 +
 tools/objtool/include/objtool/warn.h    |  17 +-
 12 files changed, 1122 insertions(+), 267 deletions(-)
 create mode 100644 tools/objtool/disas.c

-- 
2.43.5


^ permalink raw reply	[flat|nested] 32+ messages in thread

end of thread, other threads:[~2025-06-11 19:25 UTC | newest]

Thread overview: 32+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-06-06 15:34 [RFC 00/13] objtool: Function validation tracing Alexandre Chartre
2025-06-06 15:34 ` [RFC 01/13] objtool: Move disassembly functions to a separated file Alexandre Chartre
2025-06-06 15:34 ` [RFC 02/13] objtool: Create disassembly context Alexandre Chartre
2025-06-10 21:12   ` Josh Poimboeuf
2025-06-06 15:34 ` [RFC 03/13] objtool: Disassemble code with libopcodes instead of running objdump Alexandre Chartre
2025-06-10 21:22   ` Josh Poimboeuf
2025-06-11 12:23   ` Peter Zijlstra
2025-06-11 13:35     ` Alexandre Chartre
2025-06-11 19:25       ` Josh Poimboeuf
2025-06-06 15:34 ` [RFC 04/13] objtool: Print symbol during disassembly Alexandre Chartre
2025-06-10 21:55   ` Josh Poimboeuf
2025-06-06 15:34 ` [RFC 05/13] objtool: Store instruction disassembly result Alexandre Chartre
2025-06-10 22:40   ` Josh Poimboeuf
2025-06-06 15:34 ` [RFC 06/13] objtool: Disassemble instruction on warning or backtrace Alexandre Chartre
2025-06-06 15:34 ` [RFC 07/13] objtool: Extract code to validate instruction from the validate branch loop Alexandre Chartre
2025-06-10 23:31   ` Josh Poimboeuf
2025-06-06 15:34 ` [RFC 08/13] objtool: Record symbol name max length Alexandre Chartre
2025-06-06 15:34 ` [RFC 09/13] objtool: Add option to trace function validation Alexandre Chartre
2025-06-11  0:48   ` Josh Poimboeuf
2025-06-06 15:34 ` [RFC 10/13] objtool: Trace instruction state changes during " Alexandre Chartre
2025-06-11  1:23   ` Josh Poimboeuf
2025-06-06 15:34 ` [RFC 11/13] objtool: Improve register reporting " Alexandre Chartre
2025-06-06 15:34 ` [RFC 12/13] objtool: Improve tracing of alternative instructions Alexandre Chartre
2025-06-06 15:34 ` [RFC 13/13] objtool: Do not validate IBT for .return_sites and .call_sites Alexandre Chartre
2025-06-06 15:58 ` [RFC 00/13] objtool: Function validation tracing Josh Poimboeuf
2025-06-06 19:29   ` Alexandre Chartre
2025-06-09 18:31 ` Josh Poimboeuf
2025-06-10  7:07   ` Alexandre Chartre
2025-06-10 13:00     ` Alexandre Chartre
2025-06-10 21:05       ` Josh Poimboeuf
2025-06-11  6:00         ` Alexandre Chartre
2025-06-11 14:20           ` Peter Zijlstra

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®