From: Alexandre Chartre <alexandre.chartre@oracle.com>
To: linux-kernel@vger.kernel.org, mingo@kernel.org,
jpoimboe@kernel.org, peterz@infradead.org
Cc: alexandre.chartre@oracle.com
Subject: [RFC 00/13] objtool: Function validation tracing
Date: Fri, 6 Jun 2025 17:34:27 +0200 [thread overview]
Message-ID: <20250606153440.865808-1-alexandre.chartre@oracle.com> (raw)
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
next reply other threads:[~2025-06-06 15:34 UTC|newest]
Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-06-06 15:34 Alexandre Chartre [this message]
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
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250606153440.865808-1-alexandre.chartre@oracle.com \
--to=alexandre.chartre@oracle.com \
--cc=jpoimboe@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@kernel.org \
--cc=peterz@infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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®