Gentoo Archives: gentoo-commits

From: Mike Pagano <mpagano@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] proj/linux-patches:4.9 commit in: /
Date: Tue, 05 Jun 2018 11:21:53
Message-Id: 1528197695.c393ffebe2f246310c5766893e76a98ec467000d.mpagano@gentoo
1 commit: c393ffebe2f246310c5766893e76a98ec467000d
2 Author: Mike Pagano <mpagano <AT> gentoo <DOT> org>
3 AuthorDate: Tue Jun 5 11:21:35 2018 +0000
4 Commit: Mike Pagano <mpagano <AT> gentoo <DOT> org>
5 CommitDate: Tue Jun 5 11:21:35 2018 +0000
6 URL: https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=c393ffeb
7
8 Linux patch 4.9.106
9
10 0000_README | 4 +
11 1105_linux-4.9.106.patch | 13260 +++++++++++++++++++++++++++++++++++++++++++++
12 2 files changed, 13264 insertions(+)
13
14 diff --git a/0000_README b/0000_README
15 index acb7925..d5b0351 100644
16 --- a/0000_README
17 +++ b/0000_README
18 @@ -463,6 +463,10 @@ Patch: 1104_linux-4.9.105.patch
19 From: http://www.kernel.org
20 Desc: Linux 4.9.105
21
22 +Patch: 1105_linux-4.9.106.patch
23 +From: http://www.kernel.org
24 +Desc: Linux 4.9.106
25 +
26 Patch: 1500_XATTR_USER_PREFIX.patch
27 From: https://bugs.gentoo.org/show_bug.cgi?id=470644
28 Desc: Support for namespace user.pax.* on tmpfs.
29
30 diff --git a/1105_linux-4.9.106.patch b/1105_linux-4.9.106.patch
31 new file mode 100644
32 index 0000000..ccb7913
33 --- /dev/null
34 +++ b/1105_linux-4.9.106.patch
35 @@ -0,0 +1,13260 @@
36 +diff --git a/Makefile b/Makefile
37 +index 7d06dba3fde8..48d87e3a36c1 100644
38 +--- a/Makefile
39 ++++ b/Makefile
40 +@@ -1,6 +1,6 @@
41 + VERSION = 4
42 + PATCHLEVEL = 9
43 +-SUBLEVEL = 105
44 ++SUBLEVEL = 106
45 + EXTRAVERSION =
46 + NAME = Roaring Lionus
47 +
48 +diff --git a/arch/x86/crypto/Makefile b/arch/x86/crypto/Makefile
49 +index 34b3fa2889d1..9e32d40d71bd 100644
50 +--- a/arch/x86/crypto/Makefile
51 ++++ b/arch/x86/crypto/Makefile
52 +@@ -2,6 +2,8 @@
53 + # Arch-specific CryptoAPI modules.
54 + #
55 +
56 ++OBJECT_FILES_NON_STANDARD := y
57 ++
58 + avx_supported := $(call as-instr,vpxor %xmm0$(comma)%xmm0$(comma)%xmm0,yes,no)
59 + avx2_supported := $(call as-instr,vpgatherdd %ymm0$(comma)(%eax$(comma)%ymm1\
60 + $(comma)4)$(comma)%ymm2,yes,no)
61 +diff --git a/arch/x86/crypto/sha1-mb/Makefile b/arch/x86/crypto/sha1-mb/Makefile
62 +index 2f8756375df5..2e14acc3da25 100644
63 +--- a/arch/x86/crypto/sha1-mb/Makefile
64 ++++ b/arch/x86/crypto/sha1-mb/Makefile
65 +@@ -2,6 +2,8 @@
66 + # Arch-specific CryptoAPI modules.
67 + #
68 +
69 ++OBJECT_FILES_NON_STANDARD := y
70 ++
71 + avx2_supported := $(call as-instr,vpgatherdd %ymm0$(comma)(%eax$(comma)%ymm1\
72 + $(comma)4)$(comma)%ymm2,yes,no)
73 + ifeq ($(avx2_supported),yes)
74 +diff --git a/arch/x86/crypto/sha256-mb/Makefile b/arch/x86/crypto/sha256-mb/Makefile
75 +index 41089e7c400c..45b4fca6c4a8 100644
76 +--- a/arch/x86/crypto/sha256-mb/Makefile
77 ++++ b/arch/x86/crypto/sha256-mb/Makefile
78 +@@ -2,6 +2,8 @@
79 + # Arch-specific CryptoAPI modules.
80 + #
81 +
82 ++OBJECT_FILES_NON_STANDARD := y
83 ++
84 + avx2_supported := $(call as-instr,vpgatherdd %ymm0$(comma)(%eax$(comma)%ymm1\
85 + $(comma)4)$(comma)%ymm2,yes,no)
86 + ifeq ($(avx2_supported),yes)
87 +diff --git a/arch/x86/include/asm/orc_types.h b/arch/x86/include/asm/orc_types.h
88 +new file mode 100644
89 +index 000000000000..7dc777a6cb40
90 +--- /dev/null
91 ++++ b/arch/x86/include/asm/orc_types.h
92 +@@ -0,0 +1,107 @@
93 ++/*
94 ++ * Copyright (C) 2017 Josh Poimboeuf <jpoimboe@××××××.com>
95 ++ *
96 ++ * This program is free software; you can redistribute it and/or
97 ++ * modify it under the terms of the GNU General Public License
98 ++ * as published by the Free Software Foundation; either version 2
99 ++ * of the License, or (at your option) any later version.
100 ++ *
101 ++ * This program is distributed in the hope that it will be useful,
102 ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
103 ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
104 ++ * GNU General Public License for more details.
105 ++ *
106 ++ * You should have received a copy of the GNU General Public License
107 ++ * along with this program; if not, see <http://www.gnu.org/licenses/>.
108 ++ */
109 ++
110 ++#ifndef _ORC_TYPES_H
111 ++#define _ORC_TYPES_H
112 ++
113 ++#include <linux/types.h>
114 ++#include <linux/compiler.h>
115 ++
116 ++/*
117 ++ * The ORC_REG_* registers are base registers which are used to find other
118 ++ * registers on the stack.
119 ++ *
120 ++ * ORC_REG_PREV_SP, also known as DWARF Call Frame Address (CFA), is the
121 ++ * address of the previous frame: the caller's SP before it called the current
122 ++ * function.
123 ++ *
124 ++ * ORC_REG_UNDEFINED means the corresponding register's value didn't change in
125 ++ * the current frame.
126 ++ *
127 ++ * The most commonly used base registers are SP and BP -- which the previous SP
128 ++ * is usually based on -- and PREV_SP and UNDEFINED -- which the previous BP is
129 ++ * usually based on.
130 ++ *
131 ++ * The rest of the base registers are needed for special cases like entry code
132 ++ * and GCC realigned stacks.
133 ++ */
134 ++#define ORC_REG_UNDEFINED 0
135 ++#define ORC_REG_PREV_SP 1
136 ++#define ORC_REG_DX 2
137 ++#define ORC_REG_DI 3
138 ++#define ORC_REG_BP 4
139 ++#define ORC_REG_SP 5
140 ++#define ORC_REG_R10 6
141 ++#define ORC_REG_R13 7
142 ++#define ORC_REG_BP_INDIRECT 8
143 ++#define ORC_REG_SP_INDIRECT 9
144 ++#define ORC_REG_MAX 15
145 ++
146 ++/*
147 ++ * ORC_TYPE_CALL: Indicates that sp_reg+sp_offset resolves to PREV_SP (the
148 ++ * caller's SP right before it made the call). Used for all callable
149 ++ * functions, i.e. all C code and all callable asm functions.
150 ++ *
151 ++ * ORC_TYPE_REGS: Used in entry code to indicate that sp_reg+sp_offset points
152 ++ * to a fully populated pt_regs from a syscall, interrupt, or exception.
153 ++ *
154 ++ * ORC_TYPE_REGS_IRET: Used in entry code to indicate that sp_reg+sp_offset
155 ++ * points to the iret return frame.
156 ++ *
157 ++ * The UNWIND_HINT macros are used only for the unwind_hint struct. They
158 ++ * aren't used in struct orc_entry due to size and complexity constraints.
159 ++ * Objtool converts them to real types when it converts the hints to orc
160 ++ * entries.
161 ++ */
162 ++#define ORC_TYPE_CALL 0
163 ++#define ORC_TYPE_REGS 1
164 ++#define ORC_TYPE_REGS_IRET 2
165 ++#define UNWIND_HINT_TYPE_SAVE 3
166 ++#define UNWIND_HINT_TYPE_RESTORE 4
167 ++
168 ++#ifndef __ASSEMBLY__
169 ++/*
170 ++ * This struct is more or less a vastly simplified version of the DWARF Call
171 ++ * Frame Information standard. It contains only the necessary parts of DWARF
172 ++ * CFI, simplified for ease of access by the in-kernel unwinder. It tells the
173 ++ * unwinder how to find the previous SP and BP (and sometimes entry regs) on
174 ++ * the stack for a given code address. Each instance of the struct corresponds
175 ++ * to one or more code locations.
176 ++ */
177 ++struct orc_entry {
178 ++ s16 sp_offset;
179 ++ s16 bp_offset;
180 ++ unsigned sp_reg:4;
181 ++ unsigned bp_reg:4;
182 ++ unsigned type:2;
183 ++};
184 ++
185 ++/*
186 ++ * This struct is used by asm and inline asm code to manually annotate the
187 ++ * location of registers on the stack for the ORC unwinder.
188 ++ *
189 ++ * Type can be either ORC_TYPE_* or UNWIND_HINT_TYPE_*.
190 ++ */
191 ++struct unwind_hint {
192 ++ u32 ip;
193 ++ s16 sp_offset;
194 ++ u8 sp_reg;
195 ++ u8 type;
196 ++};
197 ++#endif /* __ASSEMBLY__ */
198 ++
199 ++#endif /* _ORC_TYPES_H */
200 +diff --git a/arch/x86/include/asm/unwind_hints.h b/arch/x86/include/asm/unwind_hints.h
201 +new file mode 100644
202 +index 000000000000..5e02b11c9b86
203 +--- /dev/null
204 ++++ b/arch/x86/include/asm/unwind_hints.h
205 +@@ -0,0 +1,103 @@
206 ++#ifndef _ASM_X86_UNWIND_HINTS_H
207 ++#define _ASM_X86_UNWIND_HINTS_H
208 ++
209 ++#include "orc_types.h"
210 ++
211 ++#ifdef __ASSEMBLY__
212 ++
213 ++/*
214 ++ * In asm, there are two kinds of code: normal C-type callable functions and
215 ++ * the rest. The normal callable functions can be called by other code, and
216 ++ * don't do anything unusual with the stack. Such normal callable functions
217 ++ * are annotated with the ENTRY/ENDPROC macros. Most asm code falls in this
218 ++ * category. In this case, no special debugging annotations are needed because
219 ++ * objtool can automatically generate the ORC data for the ORC unwinder to read
220 ++ * at runtime.
221 ++ *
222 ++ * Anything which doesn't fall into the above category, such as syscall and
223 ++ * interrupt handlers, tends to not be called directly by other functions, and
224 ++ * often does unusual non-C-function-type things with the stack pointer. Such
225 ++ * code needs to be annotated such that objtool can understand it. The
226 ++ * following CFI hint macros are for this type of code.
227 ++ *
228 ++ * These macros provide hints to objtool about the state of the stack at each
229 ++ * instruction. Objtool starts from the hints and follows the code flow,
230 ++ * making automatic CFI adjustments when it sees pushes and pops, filling out
231 ++ * the debuginfo as necessary. It will also warn if it sees any
232 ++ * inconsistencies.
233 ++ */
234 ++.macro UNWIND_HINT sp_reg=ORC_REG_SP sp_offset=0 type=ORC_TYPE_CALL
235 ++#ifdef CONFIG_STACK_VALIDATION
236 ++.Lunwind_hint_ip_\@:
237 ++ .pushsection .discard.unwind_hints
238 ++ /* struct unwind_hint */
239 ++ .long .Lunwind_hint_ip_\@ - .
240 ++ .short \sp_offset
241 ++ .byte \sp_reg
242 ++ .byte \type
243 ++ .popsection
244 ++#endif
245 ++.endm
246 ++
247 ++.macro UNWIND_HINT_EMPTY
248 ++ UNWIND_HINT sp_reg=ORC_REG_UNDEFINED
249 ++.endm
250 ++
251 ++.macro UNWIND_HINT_REGS base=%rsp offset=0 indirect=0 extra=1 iret=0
252 ++ .if \base == %rsp && \indirect
253 ++ .set sp_reg, ORC_REG_SP_INDIRECT
254 ++ .elseif \base == %rsp
255 ++ .set sp_reg, ORC_REG_SP
256 ++ .elseif \base == %rbp
257 ++ .set sp_reg, ORC_REG_BP
258 ++ .elseif \base == %rdi
259 ++ .set sp_reg, ORC_REG_DI
260 ++ .elseif \base == %rdx
261 ++ .set sp_reg, ORC_REG_DX
262 ++ .elseif \base == %r10
263 ++ .set sp_reg, ORC_REG_R10
264 ++ .else
265 ++ .error "UNWIND_HINT_REGS: bad base register"
266 ++ .endif
267 ++
268 ++ .set sp_offset, \offset
269 ++
270 ++ .if \iret
271 ++ .set type, ORC_TYPE_REGS_IRET
272 ++ .elseif \extra == 0
273 ++ .set type, ORC_TYPE_REGS_IRET
274 ++ .set sp_offset, \offset + (16*8)
275 ++ .else
276 ++ .set type, ORC_TYPE_REGS
277 ++ .endif
278 ++
279 ++ UNWIND_HINT sp_reg=sp_reg sp_offset=sp_offset type=type
280 ++.endm
281 ++
282 ++.macro UNWIND_HINT_IRET_REGS base=%rsp offset=0
283 ++ UNWIND_HINT_REGS base=\base offset=\offset iret=1
284 ++.endm
285 ++
286 ++.macro UNWIND_HINT_FUNC sp_offset=8
287 ++ UNWIND_HINT sp_offset=\sp_offset
288 ++.endm
289 ++
290 ++#else /* !__ASSEMBLY__ */
291 ++
292 ++#define UNWIND_HINT(sp_reg, sp_offset, type) \
293 ++ "987: \n\t" \
294 ++ ".pushsection .discard.unwind_hints\n\t" \
295 ++ /* struct unwind_hint */ \
296 ++ ".long 987b - .\n\t" \
297 ++ ".short " __stringify(sp_offset) "\n\t" \
298 ++ ".byte " __stringify(sp_reg) "\n\t" \
299 ++ ".byte " __stringify(type) "\n\t" \
300 ++ ".popsection\n\t"
301 ++
302 ++#define UNWIND_HINT_SAVE UNWIND_HINT(0, 0, UNWIND_HINT_TYPE_SAVE)
303 ++
304 ++#define UNWIND_HINT_RESTORE UNWIND_HINT(0, 0, UNWIND_HINT_TYPE_RESTORE)
305 ++
306 ++#endif /* __ASSEMBLY__ */
307 ++
308 ++#endif /* _ASM_X86_UNWIND_HINTS_H */
309 +diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
310 +index 79076d75bdbf..4c9c61517613 100644
311 +--- a/arch/x86/kernel/Makefile
312 ++++ b/arch/x86/kernel/Makefile
313 +@@ -29,6 +29,7 @@ OBJECT_FILES_NON_STANDARD_head_$(BITS).o := y
314 + OBJECT_FILES_NON_STANDARD_relocate_kernel_$(BITS).o := y
315 + OBJECT_FILES_NON_STANDARD_mcount_$(BITS).o := y
316 + OBJECT_FILES_NON_STANDARD_test_nx.o := y
317 ++OBJECT_FILES_NON_STANDARD_paravirt_patch_$(BITS).o := y
318 +
319 + # If instrumentation of this dir is enabled, boot hangs during first second.
320 + # Probably could be more selective here, but note that files related to irqs,
321 +diff --git a/arch/x86/kernel/acpi/Makefile b/arch/x86/kernel/acpi/Makefile
322 +index 26b78d86f25a..85a9e17e0dbc 100644
323 +--- a/arch/x86/kernel/acpi/Makefile
324 ++++ b/arch/x86/kernel/acpi/Makefile
325 +@@ -1,3 +1,5 @@
326 ++OBJECT_FILES_NON_STANDARD_wakeup_$(BITS).o := y
327 ++
328 + obj-$(CONFIG_ACPI) += boot.o
329 + obj-$(CONFIG_ACPI_SLEEP) += sleep.o wakeup_$(BITS).o
330 + obj-$(CONFIG_ACPI_APEI) += apei.o
331 +diff --git a/arch/x86/kernel/kprobes/opt.c b/arch/x86/kernel/kprobes/opt.c
332 +index fa671b90c374..1808a9cc7701 100644
333 +--- a/arch/x86/kernel/kprobes/opt.c
334 ++++ b/arch/x86/kernel/kprobes/opt.c
335 +@@ -28,6 +28,7 @@
336 + #include <linux/kdebug.h>
337 + #include <linux/kallsyms.h>
338 + #include <linux/ftrace.h>
339 ++#include <linux/frame.h>
340 +
341 + #include <asm/text-patching.h>
342 + #include <asm/cacheflush.h>
343 +@@ -91,6 +92,7 @@ static void synthesize_set_arg1(kprobe_opcode_t *addr, unsigned long val)
344 + }
345 +
346 + asm (
347 ++ "optprobe_template_func:\n"
348 + ".global optprobe_template_entry\n"
349 + "optprobe_template_entry:\n"
350 + #ifdef CONFIG_X86_64
351 +@@ -128,7 +130,12 @@ asm (
352 + " popf\n"
353 + #endif
354 + ".global optprobe_template_end\n"
355 +- "optprobe_template_end:\n");
356 ++ "optprobe_template_end:\n"
357 ++ ".type optprobe_template_func, @function\n"
358 ++ ".size optprobe_template_func, .-optprobe_template_func\n");
359 ++
360 ++void optprobe_template_func(void);
361 ++STACK_FRAME_NON_STANDARD(optprobe_template_func);
362 +
363 + #define TMPL_MOVE_IDX \
364 + ((long)&optprobe_template_val - (long)&optprobe_template_entry)
365 +diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c
366 +index 03f21dbfaa9d..4a12362a194a 100644
367 +--- a/arch/x86/kernel/reboot.c
368 ++++ b/arch/x86/kernel/reboot.c
369 +@@ -9,6 +9,7 @@
370 + #include <linux/sched.h>
371 + #include <linux/tboot.h>
372 + #include <linux/delay.h>
373 ++#include <linux/frame.h>
374 + #include <acpi/reboot.h>
375 + #include <asm/io.h>
376 + #include <asm/apic.h>
377 +@@ -127,6 +128,7 @@ void __noreturn machine_real_restart(unsigned int type)
378 + #ifdef CONFIG_APM_MODULE
379 + EXPORT_SYMBOL(machine_real_restart);
380 + #endif
381 ++STACK_FRAME_NON_STANDARD(machine_real_restart);
382 +
383 + /*
384 + * Some Apple MacBook and MacBookPro's needs reboot=p to be able to reboot
385 +diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S
386 +index c7194e97c3d4..4ef267fb635a 100644
387 +--- a/arch/x86/kernel/vmlinux.lds.S
388 ++++ b/arch/x86/kernel/vmlinux.lds.S
389 +@@ -353,6 +353,7 @@ SECTIONS
390 + /DISCARD/ : {
391 + *(.eh_frame)
392 + *(__func_stack_frame_non_standard)
393 ++ *(__unreachable)
394 + }
395 + }
396 +
397 +diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
398 +index a27f9e442ffc..c4cd1280ac3e 100644
399 +--- a/arch/x86/kvm/svm.c
400 ++++ b/arch/x86/kvm/svm.c
401 +@@ -36,6 +36,7 @@
402 + #include <linux/slab.h>
403 + #include <linux/amd-iommu.h>
404 + #include <linux/hashtable.h>
405 ++#include <linux/frame.h>
406 +
407 + #include <asm/apic.h>
408 + #include <asm/perf_event.h>
409 +@@ -5111,6 +5112,7 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu)
410 +
411 + mark_all_clean(svm->vmcb);
412 + }
413 ++STACK_FRAME_NON_STANDARD(svm_vcpu_run);
414 +
415 + static void svm_set_cr3(struct kvm_vcpu *vcpu, unsigned long root)
416 + {
417 +diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
418 +index 2827a9622d97..4a66a620fc17 100644
419 +--- a/arch/x86/kvm/vmx.c
420 ++++ b/arch/x86/kvm/vmx.c
421 +@@ -33,6 +33,7 @@
422 + #include <linux/slab.h>
423 + #include <linux/tboot.h>
424 + #include <linux/hrtimer.h>
425 ++#include <linux/frame.h>
426 + #include <linux/nospec.h>
427 + #include "kvm_cache_regs.h"
428 + #include "x86.h"
429 +@@ -8698,6 +8699,7 @@ static void vmx_handle_external_intr(struct kvm_vcpu *vcpu)
430 + );
431 + }
432 + }
433 ++STACK_FRAME_NON_STANDARD(vmx_handle_external_intr);
434 +
435 + static bool vmx_has_emulated_msr(int index)
436 + {
437 +@@ -9138,6 +9140,7 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu)
438 + vmx_recover_nmi_blocking(vmx);
439 + vmx_complete_interrupts(vmx);
440 + }
441 ++STACK_FRAME_NON_STANDARD(vmx_vcpu_run);
442 +
443 + static void vmx_load_vmcs01(struct kvm_vcpu *vcpu)
444 + {
445 +diff --git a/arch/x86/lib/msr-reg.S b/arch/x86/lib/msr-reg.S
446 +index c81556409bbb..10ffa7e8519f 100644
447 +--- a/arch/x86/lib/msr-reg.S
448 ++++ b/arch/x86/lib/msr-reg.S
449 +@@ -13,14 +13,14 @@
450 + .macro op_safe_regs op
451 + ENTRY(\op\()_safe_regs)
452 + pushq %rbx
453 +- pushq %rbp
454 ++ pushq %r12
455 + movq %rdi, %r10 /* Save pointer */
456 + xorl %r11d, %r11d /* Return value */
457 + movl (%rdi), %eax
458 + movl 4(%rdi), %ecx
459 + movl 8(%rdi), %edx
460 + movl 12(%rdi), %ebx
461 +- movl 20(%rdi), %ebp
462 ++ movl 20(%rdi), %r12d
463 + movl 24(%rdi), %esi
464 + movl 28(%rdi), %edi
465 + 1: \op
466 +@@ -29,10 +29,10 @@ ENTRY(\op\()_safe_regs)
467 + movl %ecx, 4(%r10)
468 + movl %edx, 8(%r10)
469 + movl %ebx, 12(%r10)
470 +- movl %ebp, 20(%r10)
471 ++ movl %r12d, 20(%r10)
472 + movl %esi, 24(%r10)
473 + movl %edi, 28(%r10)
474 +- popq %rbp
475 ++ popq %r12
476 + popq %rbx
477 + ret
478 + 3:
479 +diff --git a/arch/x86/net/Makefile b/arch/x86/net/Makefile
480 +index 90568c33ddb0..fefb4b619598 100644
481 +--- a/arch/x86/net/Makefile
482 ++++ b/arch/x86/net/Makefile
483 +@@ -1,4 +1,6 @@
484 + #
485 + # Arch-specific network modules
486 + #
487 ++OBJECT_FILES_NON_STANDARD_bpf_jit.o += y
488 ++
489 + obj-$(CONFIG_BPF_JIT) += bpf_jit.o bpf_jit_comp.o
490 +diff --git a/arch/x86/platform/efi/Makefile b/arch/x86/platform/efi/Makefile
491 +index 066619b0700c..7a255022933e 100644
492 +--- a/arch/x86/platform/efi/Makefile
493 ++++ b/arch/x86/platform/efi/Makefile
494 +@@ -1,4 +1,5 @@
495 + OBJECT_FILES_NON_STANDARD_efi_thunk_$(BITS).o := y
496 ++OBJECT_FILES_NON_STANDARD_efi_stub_$(BITS).o := y
497 +
498 + obj-$(CONFIG_EFI) += quirks.o efi.o efi_$(BITS).o efi_stub_$(BITS).o
499 + obj-$(CONFIG_ACPI_BGRT) += efi-bgrt.o
500 +diff --git a/arch/x86/power/Makefile b/arch/x86/power/Makefile
501 +index a6a198c33623..05041871ac90 100644
502 +--- a/arch/x86/power/Makefile
503 ++++ b/arch/x86/power/Makefile
504 +@@ -1,3 +1,5 @@
505 ++OBJECT_FILES_NON_STANDARD_hibernate_asm_$(BITS).o := y
506 ++
507 + # __restore_processor_state() restores %gs after S3 resume and so should not
508 + # itself be stack-protected
509 + nostackp := $(call cc-option, -fno-stack-protector)
510 +diff --git a/arch/x86/xen/Makefile b/arch/x86/xen/Makefile
511 +index e47e52787d32..4a54059f42ba 100644
512 +--- a/arch/x86/xen/Makefile
513 ++++ b/arch/x86/xen/Makefile
514 +@@ -1,3 +1,6 @@
515 ++OBJECT_FILES_NON_STANDARD_xen-asm_$(BITS).o := y
516 ++OBJECT_FILES_NON_STANDARD_xen-pvh.o := y
517 ++
518 + ifdef CONFIG_FUNCTION_TRACER
519 + # Do not profile debug and lowlevel utilities
520 + CFLAGS_REMOVE_spinlock.o = -pg
521 +diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
522 +index 081437b5f381..e3a3f5a64884 100644
523 +--- a/arch/x86/xen/enlighten.c
524 ++++ b/arch/x86/xen/enlighten.c
525 +@@ -75,6 +75,7 @@
526 + #include <asm/mwait.h>
527 + #include <asm/pci_x86.h>
528 + #include <asm/cpu.h>
529 ++#include <asm/unwind_hints.h>
530 +
531 + #ifdef CONFIG_ACPI
532 + #include <linux/acpi.h>
533 +@@ -1452,10 +1453,12 @@ static void __ref xen_setup_gdt(int cpu)
534 + * GDT. The new GDT has __KERNEL_CS with CS.L = 1
535 + * and we are jumping to reload it.
536 + */
537 +- asm volatile ("pushq %0\n"
538 ++ asm volatile (UNWIND_HINT_SAVE
539 ++ "pushq %0\n"
540 + "leaq 1f(%%rip),%0\n"
541 + "pushq %0\n"
542 + "lretq\n"
543 ++ UNWIND_HINT_RESTORE
544 + "1:\n"
545 + : "=&r" (dummy) : "0" (__KERNEL_CS));
546 +
547 +diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h
548 +index a1b1de17455c..2214b2f9c73c 100644
549 +--- a/include/linux/compiler-gcc.h
550 ++++ b/include/linux/compiler-gcc.h
551 +@@ -203,6 +203,17 @@
552 + #endif
553 + #endif
554 +
555 ++#ifdef CONFIG_STACK_VALIDATION
556 ++#define annotate_unreachable() ({ \
557 ++ asm("1:\t\n" \
558 ++ ".pushsection __unreachable, \"a\"\t\n" \
559 ++ ".long 1b\t\n" \
560 ++ ".popsection\t\n"); \
561 ++})
562 ++#else
563 ++#define annotate_unreachable()
564 ++#endif
565 ++
566 + /*
567 + * Mark a position in code as unreachable. This can be used to
568 + * suppress control flow warnings after asm blocks that transfer
569 +@@ -212,7 +223,8 @@
570 + * this in the preprocessor, but we can live with this because they're
571 + * unreleased. Really, we need to have autoconf for the kernel.
572 + */
573 +-#define unreachable() __builtin_unreachable()
574 ++#define unreachable() \
575 ++ do { annotate_unreachable(); __builtin_unreachable(); } while (0)
576 +
577 + /* Mark a function definition as prohibited from being cloned. */
578 + #define __noclone __attribute__((__noclone__, __optimize__("no-tracer")))
579 +diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c
580 +index 561675589511..f5ab72ebda11 100644
581 +--- a/kernel/kexec_core.c
582 ++++ b/kernel/kexec_core.c
583 +@@ -38,6 +38,7 @@
584 + #include <linux/syscore_ops.h>
585 + #include <linux/compiler.h>
586 + #include <linux/hugetlb.h>
587 ++#include <linux/frame.h>
588 +
589 + #include <asm/page.h>
590 + #include <asm/sections.h>
591 +@@ -878,7 +879,7 @@ int kexec_load_disabled;
592 + * only when panic_cpu holds the current CPU number; this is the only CPU
593 + * which processes crash_kexec routines.
594 + */
595 +-void __crash_kexec(struct pt_regs *regs)
596 ++void __noclone __crash_kexec(struct pt_regs *regs)
597 + {
598 + /* Take the kexec_mutex here to prevent sys_kexec_load
599 + * running on one cpu from replacing the crash kernel
600 +@@ -900,6 +901,7 @@ void __crash_kexec(struct pt_regs *regs)
601 + mutex_unlock(&kexec_mutex);
602 + }
603 + }
604 ++STACK_FRAME_NON_STANDARD(__crash_kexec);
605 +
606 + void crash_kexec(struct pt_regs *regs)
607 + {
608 +diff --git a/tools/arch/arm/include/uapi/asm/kvm.h b/tools/arch/arm/include/uapi/asm/kvm.h
609 +index a2b3eb313a25..0b8cf31d8416 100644
610 +--- a/tools/arch/arm/include/uapi/asm/kvm.h
611 ++++ b/tools/arch/arm/include/uapi/asm/kvm.h
612 +@@ -84,6 +84,13 @@ struct kvm_regs {
613 + #define KVM_VGIC_V2_DIST_SIZE 0x1000
614 + #define KVM_VGIC_V2_CPU_SIZE 0x2000
615 +
616 ++/* Supported VGICv3 address types */
617 ++#define KVM_VGIC_V3_ADDR_TYPE_DIST 2
618 ++#define KVM_VGIC_V3_ADDR_TYPE_REDIST 3
619 ++
620 ++#define KVM_VGIC_V3_DIST_SIZE SZ_64K
621 ++#define KVM_VGIC_V3_REDIST_SIZE (2 * SZ_64K)
622 ++
623 + #define KVM_ARM_VCPU_POWER_OFF 0 /* CPU is started in OFF state */
624 + #define KVM_ARM_VCPU_PSCI_0_2 1 /* CPU uses PSCI v0.2 */
625 +
626 +@@ -166,6 +173,12 @@ struct kvm_arch_memory_slot {
627 + #define KVM_REG_ARM_VFP_FPINST 0x1009
628 + #define KVM_REG_ARM_VFP_FPINST2 0x100A
629 +
630 ++/* KVM-as-firmware specific pseudo-registers */
631 ++#define KVM_REG_ARM_FW (0x0014 << KVM_REG_ARM_COPROC_SHIFT)
632 ++#define KVM_REG_ARM_FW_REG(r) (KVM_REG_ARM | KVM_REG_SIZE_U64 | \
633 ++ KVM_REG_ARM_FW | ((r) & 0xffff))
634 ++#define KVM_REG_ARM_PSCI_VERSION KVM_REG_ARM_FW_REG(0)
635 ++
636 + /* Device Control API: ARM VGIC */
637 + #define KVM_DEV_ARM_VGIC_GRP_ADDR 0
638 + #define KVM_DEV_ARM_VGIC_GRP_DIST_REGS 1
639 +diff --git a/tools/arch/arm64/include/uapi/asm/kvm.h b/tools/arch/arm64/include/uapi/asm/kvm.h
640 +index 3051f86a9b5f..702de7a2b024 100644
641 +--- a/tools/arch/arm64/include/uapi/asm/kvm.h
642 ++++ b/tools/arch/arm64/include/uapi/asm/kvm.h
643 +@@ -195,6 +195,12 @@ struct kvm_arch_memory_slot {
644 + #define KVM_REG_ARM_TIMER_CNT ARM64_SYS_REG(3, 3, 14, 3, 2)
645 + #define KVM_REG_ARM_TIMER_CVAL ARM64_SYS_REG(3, 3, 14, 0, 2)
646 +
647 ++/* KVM-as-firmware specific pseudo-registers */
648 ++#define KVM_REG_ARM_FW (0x0014 << KVM_REG_ARM_COPROC_SHIFT)
649 ++#define KVM_REG_ARM_FW_REG(r) (KVM_REG_ARM64 | KVM_REG_SIZE_U64 | \
650 ++ KVM_REG_ARM_FW | ((r) & 0xffff))
651 ++#define KVM_REG_ARM_PSCI_VERSION KVM_REG_ARM_FW_REG(0)
652 ++
653 + /* Device Control API: ARM VGIC */
654 + #define KVM_DEV_ARM_VGIC_GRP_ADDR 0
655 + #define KVM_DEV_ARM_VGIC_GRP_DIST_REGS 1
656 +diff --git a/tools/arch/powerpc/include/uapi/asm/kvm.h b/tools/arch/powerpc/include/uapi/asm/kvm.h
657 +index c93cf35ce379..0fb1326c3ea2 100644
658 +--- a/tools/arch/powerpc/include/uapi/asm/kvm.h
659 ++++ b/tools/arch/powerpc/include/uapi/asm/kvm.h
660 +@@ -596,6 +596,7 @@ struct kvm_get_htab_header {
661 + #define KVM_REG_PPC_TM_VSCR (KVM_REG_PPC_TM | KVM_REG_SIZE_U32 | 0x67)
662 + #define KVM_REG_PPC_TM_DSCR (KVM_REG_PPC_TM | KVM_REG_SIZE_U64 | 0x68)
663 + #define KVM_REG_PPC_TM_TAR (KVM_REG_PPC_TM | KVM_REG_SIZE_U64 | 0x69)
664 ++#define KVM_REG_PPC_TM_XER (KVM_REG_PPC_TM | KVM_REG_SIZE_U64 | 0x6a)
665 +
666 + /* PPC64 eXternal Interrupt Controller Specification */
667 + #define KVM_DEV_XICS_GRP_SOURCES 1 /* 64-bit source attributes */
668 +diff --git a/tools/arch/s390/include/uapi/asm/kvm.h b/tools/arch/s390/include/uapi/asm/kvm.h
669 +index a2ffec4139ad..81c02e198527 100644
670 +--- a/tools/arch/s390/include/uapi/asm/kvm.h
671 ++++ b/tools/arch/s390/include/uapi/asm/kvm.h
672 +@@ -197,6 +197,7 @@ struct kvm_guest_debug_arch {
673 + #define KVM_SYNC_VRS (1UL << 6)
674 + #define KVM_SYNC_RICCB (1UL << 7)
675 + #define KVM_SYNC_FPRS (1UL << 8)
676 ++#define KVM_SYNC_BPBC (1UL << 10)
677 + /* definition of registers in kvm_run */
678 + struct kvm_sync_regs {
679 + __u64 prefix; /* prefix register */
680 +@@ -217,7 +218,9 @@ struct kvm_sync_regs {
681 + };
682 + __u8 reserved[512]; /* for future vector expansion */
683 + __u32 fpc; /* valid on KVM_SYNC_VRS or KVM_SYNC_FPRS */
684 +- __u8 padding[52]; /* riccb needs to be 64byte aligned */
685 ++ __u8 bpbc : 1; /* bp mode */
686 ++ __u8 reserved2 : 7;
687 ++ __u8 padding1[51]; /* riccb needs to be 64byte aligned */
688 + __u8 riccb[64]; /* runtime instrumentation controls block */
689 + };
690 +
691 +diff --git a/tools/arch/x86/include/asm/cpufeatures.h b/tools/arch/x86/include/asm/cpufeatures.h
692 +index f79669a38c0c..c278f276c9b3 100644
693 +--- a/tools/arch/x86/include/asm/cpufeatures.h
694 ++++ b/tools/arch/x86/include/asm/cpufeatures.h
695 +@@ -12,7 +12,7 @@
696 + /*
697 + * Defines x86 CPU feature bits
698 + */
699 +-#define NCAPINTS 18 /* N 32-bit words worth of info */
700 ++#define NCAPINTS 19 /* N 32-bit words worth of info */
701 + #define NBUGINTS 1 /* N 32-bit bug flags */
702 +
703 + /*
704 +@@ -189,17 +189,32 @@
705 +
706 + #define X86_FEATURE_CPB ( 7*32+ 2) /* AMD Core Performance Boost */
707 + #define X86_FEATURE_EPB ( 7*32+ 3) /* IA32_ENERGY_PERF_BIAS support */
708 ++#define X86_FEATURE_INVPCID_SINGLE ( 7*32+ 4) /* Effectively INVPCID && CR4.PCIDE=1 */
709 +
710 + #define X86_FEATURE_HW_PSTATE ( 7*32+ 8) /* AMD HW-PState */
711 + #define X86_FEATURE_PROC_FEEDBACK ( 7*32+ 9) /* AMD ProcFeedbackInterface */
712 +
713 +-#define X86_FEATURE_INTEL_PT ( 7*32+15) /* Intel Processor Trace */
714 +-#define X86_FEATURE_AVX512_4VNNIW (7*32+16) /* AVX-512 Neural Network Instructions */
715 +-#define X86_FEATURE_AVX512_4FMAPS (7*32+17) /* AVX-512 Multiply Accumulation Single precision */
716 ++#define X86_FEATURE_RETPOLINE ( 7*32+12) /* "" Generic Retpoline mitigation for Spectre variant 2 */
717 ++#define X86_FEATURE_RETPOLINE_AMD ( 7*32+13) /* "" AMD Retpoline mitigation for Spectre variant 2 */
718 ++
719 ++#define X86_FEATURE_MSR_SPEC_CTRL ( 7*32+16) /* "" MSR SPEC_CTRL is implemented */
720 ++#define X86_FEATURE_SSBD ( 7*32+17) /* Speculative Store Bypass Disable */
721 ++
722 ++#define X86_FEATURE_RSB_CTXSW ( 7*32+19) /* "" Fill RSB on context switches */
723 +
724 + /* Because the ALTERNATIVE scheme is for members of the X86_FEATURE club... */
725 + #define X86_FEATURE_KAISER ( 7*32+31) /* CONFIG_PAGE_TABLE_ISOLATION w/o nokaiser */
726 +
727 ++#define X86_FEATURE_USE_IBPB ( 7*32+21) /* "" Indirect Branch Prediction Barrier enabled */
728 ++#define X86_FEATURE_USE_IBRS_FW ( 7*32+22) /* "" Use IBRS during runtime firmware calls */
729 ++#define X86_FEATURE_SPEC_STORE_BYPASS_DISABLE ( 7*32+23) /* "" Disable Speculative Store Bypass. */
730 ++#define X86_FEATURE_LS_CFG_SSBD ( 7*32+24) /* "" AMD SSBD implementation */
731 ++#define X86_FEATURE_IBRS ( 7*32+25) /* Indirect Branch Restricted Speculation */
732 ++#define X86_FEATURE_IBPB ( 7*32+26) /* Indirect Branch Prediction Barrier */
733 ++#define X86_FEATURE_STIBP ( 7*32+27) /* Single Thread Indirect Branch Predictors */
734 ++#define X86_FEATURE_ZEN ( 7*32+28) /* "" CPU is AMD family 0x17 (Zen) */
735 ++
736 ++
737 + /* Virtualization flags: Linux defined, word 8 */
738 + #define X86_FEATURE_TPR_SHADOW ( 8*32+ 0) /* Intel TPR Shadow */
739 + #define X86_FEATURE_VNMI ( 8*32+ 1) /* Intel Virtual NMI */
740 +@@ -231,6 +246,7 @@
741 + #define X86_FEATURE_SMAP ( 9*32+20) /* Supervisor Mode Access Prevention */
742 + #define X86_FEATURE_CLFLUSHOPT ( 9*32+23) /* CLFLUSHOPT instruction */
743 + #define X86_FEATURE_CLWB ( 9*32+24) /* CLWB instruction */
744 ++#define X86_FEATURE_INTEL_PT ( 9*32+25) /* Intel Processor Trace */
745 + #define X86_FEATURE_AVX512PF ( 9*32+26) /* AVX-512 Prefetch */
746 + #define X86_FEATURE_AVX512ER ( 9*32+27) /* AVX-512 Exponential and Reciprocal */
747 + #define X86_FEATURE_AVX512CD ( 9*32+28) /* AVX-512 Conflict Detection */
748 +@@ -255,6 +271,10 @@
749 + /* AMD-defined CPU features, CPUID level 0x80000008 (ebx), word 13 */
750 + #define X86_FEATURE_CLZERO (13*32+0) /* CLZERO instruction */
751 + #define X86_FEATURE_IRPERF (13*32+1) /* Instructions Retired Count */
752 ++#define X86_FEATURE_AMD_IBPB (13*32+12) /* Indirect Branch Prediction Barrier */
753 ++#define X86_FEATURE_AMD_IBRS (13*32+14) /* Indirect Branch Restricted Speculation */
754 ++#define X86_FEATURE_AMD_STIBP (13*32+15) /* Single Thread Indirect Branch Predictors */
755 ++#define X86_FEATURE_VIRT_SSBD (13*32+25) /* Virtualized Speculative Store Bypass Disable */
756 +
757 + /* Thermal and Power Management Leaf, CPUID level 0x00000006 (eax), word 14 */
758 + #define X86_FEATURE_DTHERM (14*32+ 0) /* Digital Thermal Sensor */
759 +@@ -290,6 +310,16 @@
760 + #define X86_FEATURE_SUCCOR (17*32+1) /* Uncorrectable error containment and recovery */
761 + #define X86_FEATURE_SMCA (17*32+3) /* Scalable MCA */
762 +
763 ++
764 ++/* Intel-defined CPU features, CPUID level 0x00000007:0 (EDX), word 18 */
765 ++#define X86_FEATURE_AVX512_4VNNIW (18*32+ 2) /* AVX-512 Neural Network Instructions */
766 ++#define X86_FEATURE_AVX512_4FMAPS (18*32+ 3) /* AVX-512 Multiply Accumulation Single precision */
767 ++#define X86_FEATURE_PCONFIG (18*32+18) /* Intel PCONFIG */
768 ++#define X86_FEATURE_SPEC_CTRL (18*32+26) /* "" Speculation Control (IBRS + IBPB) */
769 ++#define X86_FEATURE_INTEL_STIBP (18*32+27) /* "" Single Thread Indirect Branch Predictors */
770 ++#define X86_FEATURE_ARCH_CAPABILITIES (18*32+29) /* IA32_ARCH_CAPABILITIES MSR (Intel) */
771 ++#define X86_FEATURE_SPEC_CTRL_SSBD (18*32+31) /* "" Speculative Store Bypass Disable */
772 ++
773 + /*
774 + * BUG word(s)
775 + */
776 +@@ -314,4 +344,10 @@
777 + #define X86_BUG_NULL_SEG X86_BUG(10) /* Nulling a selector preserves the base */
778 + #define X86_BUG_SWAPGS_FENCE X86_BUG(11) /* SWAPGS without input dep on GS */
779 + #define X86_BUG_MONITOR X86_BUG(12) /* IPI required to wake up remote CPU */
780 ++#define X86_BUG_AMD_E400 X86_BUG(13) /* CPU is among the affected by Erratum 400 */
781 ++#define X86_BUG_CPU_MELTDOWN X86_BUG(14) /* CPU is affected by meltdown attack and needs kernel page table isolation */
782 ++#define X86_BUG_SPECTRE_V1 X86_BUG(15) /* CPU is affected by Spectre variant 1 attack with conditional branches */
783 ++#define X86_BUG_SPECTRE_V2 X86_BUG(16) /* CPU is affected by Spectre variant 2 attack with indirect branches */
784 ++#define X86_BUG_SPEC_STORE_BYPASS X86_BUG(17) /* CPU is affected by speculative store bypass attack */
785 ++
786 + #endif /* _ASM_X86_CPUFEATURES_H */
787 +diff --git a/tools/arch/x86/include/asm/disabled-features.h b/tools/arch/x86/include/asm/disabled-features.h
788 +index 85599ad4d024..1f8cca459c6c 100644
789 +--- a/tools/arch/x86/include/asm/disabled-features.h
790 ++++ b/tools/arch/x86/include/asm/disabled-features.h
791 +@@ -21,11 +21,13 @@
792 + # define DISABLE_K6_MTRR (1<<(X86_FEATURE_K6_MTRR & 31))
793 + # define DISABLE_CYRIX_ARR (1<<(X86_FEATURE_CYRIX_ARR & 31))
794 + # define DISABLE_CENTAUR_MCR (1<<(X86_FEATURE_CENTAUR_MCR & 31))
795 ++# define DISABLE_PCID 0
796 + #else
797 + # define DISABLE_VME 0
798 + # define DISABLE_K6_MTRR 0
799 + # define DISABLE_CYRIX_ARR 0
800 + # define DISABLE_CENTAUR_MCR 0
801 ++# define DISABLE_PCID (1<<(X86_FEATURE_PCID & 31))
802 + #endif /* CONFIG_X86_64 */
803 +
804 + #ifdef CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS
805 +@@ -43,7 +45,7 @@
806 + #define DISABLED_MASK1 0
807 + #define DISABLED_MASK2 0
808 + #define DISABLED_MASK3 (DISABLE_CYRIX_ARR|DISABLE_CENTAUR_MCR|DISABLE_K6_MTRR)
809 +-#define DISABLED_MASK4 0
810 ++#define DISABLED_MASK4 (DISABLE_PCID)
811 + #define DISABLED_MASK5 0
812 + #define DISABLED_MASK6 0
813 + #define DISABLED_MASK7 0
814 +@@ -57,6 +59,7 @@
815 + #define DISABLED_MASK15 0
816 + #define DISABLED_MASK16 (DISABLE_PKU|DISABLE_OSPKE)
817 + #define DISABLED_MASK17 0
818 +-#define DISABLED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 18)
819 ++#define DISABLED_MASK18 0
820 ++#define DISABLED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 19)
821 +
822 + #endif /* _ASM_X86_DISABLED_FEATURES_H */
823 +diff --git a/tools/arch/x86/include/asm/required-features.h b/tools/arch/x86/include/asm/required-features.h
824 +index fac9a5c0abe9..6847d85400a8 100644
825 +--- a/tools/arch/x86/include/asm/required-features.h
826 ++++ b/tools/arch/x86/include/asm/required-features.h
827 +@@ -100,6 +100,7 @@
828 + #define REQUIRED_MASK15 0
829 + #define REQUIRED_MASK16 0
830 + #define REQUIRED_MASK17 0
831 +-#define REQUIRED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 18)
832 ++#define REQUIRED_MASK18 0
833 ++#define REQUIRED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 19)
834 +
835 + #endif /* _ASM_X86_REQUIRED_FEATURES_H */
836 +diff --git a/tools/include/asm-generic/bitops.h b/tools/include/asm-generic/bitops.h
837 +index 653d1bad77de..0304600121da 100644
838 +--- a/tools/include/asm-generic/bitops.h
839 ++++ b/tools/include/asm-generic/bitops.h
840 +@@ -13,6 +13,7 @@
841 + */
842 +
843 + #include <asm-generic/bitops/__ffs.h>
844 ++#include <asm-generic/bitops/__ffz.h>
845 + #include <asm-generic/bitops/fls.h>
846 + #include <asm-generic/bitops/__fls.h>
847 + #include <asm-generic/bitops/fls64.h>
848 +diff --git a/tools/include/asm-generic/bitops/__ffz.h b/tools/include/asm-generic/bitops/__ffz.h
849 +new file mode 100644
850 +index 000000000000..6744bd4cdf46
851 +--- /dev/null
852 ++++ b/tools/include/asm-generic/bitops/__ffz.h
853 +@@ -0,0 +1,12 @@
854 ++#ifndef _ASM_GENERIC_BITOPS_FFZ_H_
855 ++#define _ASM_GENERIC_BITOPS_FFZ_H_
856 ++
857 ++/*
858 ++ * ffz - find first zero in word.
859 ++ * @word: The word to search
860 ++ *
861 ++ * Undefined if no zero exists, so code should check against ~0UL first.
862 ++ */
863 ++#define ffz(x) __ffs(~(x))
864 ++
865 ++#endif /* _ASM_GENERIC_BITOPS_FFZ_H_ */
866 +diff --git a/tools/include/asm-generic/bitops/find.h b/tools/include/asm-generic/bitops/find.h
867 +index 31f51547fcd4..5538ecdc964a 100644
868 +--- a/tools/include/asm-generic/bitops/find.h
869 ++++ b/tools/include/asm-generic/bitops/find.h
870 +@@ -15,6 +15,21 @@ extern unsigned long find_next_bit(const unsigned long *addr, unsigned long
871 + size, unsigned long offset);
872 + #endif
873 +
874 ++#ifndef find_next_zero_bit
875 ++
876 ++/**
877 ++ * find_next_zero_bit - find the next cleared bit in a memory region
878 ++ * @addr: The address to base the search on
879 ++ * @offset: The bitnumber to start searching at
880 ++ * @size: The bitmap size in bits
881 ++ *
882 ++ * Returns the bit number of the next zero bit
883 ++ * If no bits are zero, returns @size.
884 ++ */
885 ++unsigned long find_next_zero_bit(const unsigned long *addr, unsigned long size,
886 ++ unsigned long offset);
887 ++#endif
888 ++
889 + #ifndef find_first_bit
890 +
891 + /**
892 +@@ -30,4 +45,17 @@ extern unsigned long find_first_bit(const unsigned long *addr,
893 +
894 + #endif /* find_first_bit */
895 +
896 ++#ifndef find_first_zero_bit
897 ++
898 ++/**
899 ++ * find_first_zero_bit - find the first cleared bit in a memory region
900 ++ * @addr: The address to start the search at
901 ++ * @size: The maximum number of bits to search
902 ++ *
903 ++ * Returns the bit number of the first cleared bit.
904 ++ * If no bits are zero, returns @size.
905 ++ */
906 ++unsigned long find_first_zero_bit(const unsigned long *addr, unsigned long size);
907 ++#endif
908 ++
909 + #endif /*_TOOLS_LINUX_ASM_GENERIC_BITOPS_FIND_H_ */
910 +diff --git a/tools/include/linux/atomic.h b/tools/include/linux/atomic.h
911 +index 4e3d3d18ebab..9f21fc2b092b 100644
912 +--- a/tools/include/linux/atomic.h
913 ++++ b/tools/include/linux/atomic.h
914 +@@ -3,4 +3,10 @@
915 +
916 + #include <asm/atomic.h>
917 +
918 ++/* atomic_cmpxchg_relaxed */
919 ++#ifndef atomic_cmpxchg_relaxed
920 ++#define atomic_cmpxchg_relaxed atomic_cmpxchg
921 ++#define atomic_cmpxchg_release atomic_cmpxchg
922 ++#endif /* atomic_cmpxchg_relaxed */
923 ++
924 + #endif /* __TOOLS_LINUX_ATOMIC_H */
925 +diff --git a/tools/include/linux/bitmap.h b/tools/include/linux/bitmap.h
926 +index 43c1c5021e4b..eef41d500e9e 100644
927 +--- a/tools/include/linux/bitmap.h
928 ++++ b/tools/include/linux/bitmap.h
929 +@@ -35,6 +35,32 @@ static inline void bitmap_zero(unsigned long *dst, int nbits)
930 + }
931 + }
932 +
933 ++static inline void bitmap_fill(unsigned long *dst, unsigned int nbits)
934 ++{
935 ++ unsigned int nlongs = BITS_TO_LONGS(nbits);
936 ++ if (!small_const_nbits(nbits)) {
937 ++ unsigned int len = (nlongs - 1) * sizeof(unsigned long);
938 ++ memset(dst, 0xff, len);
939 ++ }
940 ++ dst[nlongs - 1] = BITMAP_LAST_WORD_MASK(nbits);
941 ++}
942 ++
943 ++static inline int bitmap_empty(const unsigned long *src, unsigned nbits)
944 ++{
945 ++ if (small_const_nbits(nbits))
946 ++ return ! (*src & BITMAP_LAST_WORD_MASK(nbits));
947 ++
948 ++ return find_first_bit(src, nbits) == nbits;
949 ++}
950 ++
951 ++static inline int bitmap_full(const unsigned long *src, unsigned int nbits)
952 ++{
953 ++ if (small_const_nbits(nbits))
954 ++ return ! (~(*src) & BITMAP_LAST_WORD_MASK(nbits));
955 ++
956 ++ return find_first_zero_bit(src, nbits) == nbits;
957 ++}
958 ++
959 + static inline int bitmap_weight(const unsigned long *src, int nbits)
960 + {
961 + if (small_const_nbits(nbits))
962 +diff --git a/tools/include/linux/bitops.h b/tools/include/linux/bitops.h
963 +index 49c929a104ee..fc446343ff41 100644
964 +--- a/tools/include/linux/bitops.h
965 ++++ b/tools/include/linux/bitops.h
966 +@@ -39,6 +39,11 @@ extern unsigned long __sw_hweight64(__u64 w);
967 + (bit) < (size); \
968 + (bit) = find_next_bit((addr), (size), (bit) + 1))
969 +
970 ++#define for_each_clear_bit(bit, addr, size) \
971 ++ for ((bit) = find_first_zero_bit((addr), (size)); \
972 ++ (bit) < (size); \
973 ++ (bit) = find_next_zero_bit((addr), (size), (bit) + 1))
974 ++
975 + /* same as for_each_set_bit() but use bit as value to start with */
976 + #define for_each_set_bit_from(bit, addr, size) \
977 + for ((bit) = find_next_bit((addr), (size), (bit)); \
978 +diff --git a/tools/include/linux/bug.h b/tools/include/linux/bug.h
979 +new file mode 100644
980 +index 000000000000..8e4a4f49135d
981 +--- /dev/null
982 ++++ b/tools/include/linux/bug.h
983 +@@ -0,0 +1,10 @@
984 ++#ifndef _TOOLS_PERF_LINUX_BUG_H
985 ++#define _TOOLS_PERF_LINUX_BUG_H
986 ++
987 ++/* Force a compilation error if condition is true, but also produce a
988 ++ result (of value 0 and type size_t), so the expression can be used
989 ++ e.g. in a structure initializer (or where-ever else comma expressions
990 ++ aren't permitted). */
991 ++#define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); }))
992 ++
993 ++#endif /* _TOOLS_PERF_LINUX_BUG_H */
994 +diff --git a/tools/include/linux/compiler-gcc.h b/tools/include/linux/compiler-gcc.h
995 +new file mode 100644
996 +index 000000000000..825d44f89a29
997 +--- /dev/null
998 ++++ b/tools/include/linux/compiler-gcc.h
999 +@@ -0,0 +1,21 @@
1000 ++#ifndef _TOOLS_LINUX_COMPILER_H_
1001 ++#error "Please don't include <linux/compiler-gcc.h> directly, include <linux/compiler.h> instead."
1002 ++#endif
1003 ++
1004 ++/*
1005 ++ * Common definitions for all gcc versions go here.
1006 ++ */
1007 ++#define GCC_VERSION (__GNUC__ * 10000 \
1008 ++ + __GNUC_MINOR__ * 100 \
1009 ++ + __GNUC_PATCHLEVEL__)
1010 ++
1011 ++#if GCC_VERSION >= 70000 && !defined(__CHECKER__)
1012 ++# define __fallthrough __attribute__ ((fallthrough))
1013 ++#endif
1014 ++
1015 ++#if GCC_VERSION >= 40300
1016 ++# define __compiletime_error(message) __attribute__((error(message)))
1017 ++#endif /* GCC_VERSION >= 40300 */
1018 ++
1019 ++/* &a[0] degrades to a pointer: a different type from an array */
1020 ++#define __must_be_array(a) BUILD_BUG_ON_ZERO(__same_type((a), &(a)[0]))
1021 +diff --git a/tools/include/linux/compiler.h b/tools/include/linux/compiler.h
1022 +index d94179f94caa..23299d7e7160 100644
1023 +--- a/tools/include/linux/compiler.h
1024 ++++ b/tools/include/linux/compiler.h
1025 +@@ -1,6 +1,14 @@
1026 + #ifndef _TOOLS_LINUX_COMPILER_H_
1027 + #define _TOOLS_LINUX_COMPILER_H_
1028 +
1029 ++#ifdef __GNUC__
1030 ++#include <linux/compiler-gcc.h>
1031 ++#endif
1032 ++
1033 ++#ifndef __compiletime_error
1034 ++# define __compiletime_error(message)
1035 ++#endif
1036 ++
1037 + /* Optimization barrier */
1038 + /* The "volatile" is due to gcc bugs */
1039 + #define barrier() __asm__ __volatile__("": : :"memory")
1040 +@@ -9,6 +17,11 @@
1041 + # define __always_inline inline __attribute__((always_inline))
1042 + #endif
1043 +
1044 ++/* Are two types/vars the same type (ignoring qualifiers)? */
1045 ++#ifndef __same_type
1046 ++# define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b))
1047 ++#endif
1048 ++
1049 + #ifdef __ANDROID__
1050 + /*
1051 + * FIXME: Big hammer to get rid of tons of:
1052 +@@ -21,6 +34,8 @@
1053 + #endif
1054 +
1055 + #define __user
1056 ++#define __rcu
1057 ++#define __read_mostly
1058 +
1059 + #ifndef __attribute_const__
1060 + # define __attribute_const__
1061 +@@ -50,6 +65,8 @@
1062 + # define unlikely(x) __builtin_expect(!!(x), 0)
1063 + #endif
1064 +
1065 ++#define uninitialized_var(x) x = *(&(x))
1066 ++
1067 + #define ACCESS_ONCE(x) (*(volatile typeof(x) *)&(x))
1068 +
1069 + #include <linux/types.h>
1070 +@@ -128,11 +145,7 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s
1071 +
1072 +
1073 + #ifndef __fallthrough
1074 +-# if defined(__GNUC__) && __GNUC__ >= 7
1075 +-# define __fallthrough __attribute__ ((fallthrough))
1076 +-# else
1077 +-# define __fallthrough
1078 +-# endif
1079 ++# define __fallthrough
1080 + #endif
1081 +
1082 + #endif /* _TOOLS_LINUX_COMPILER_H */
1083 +diff --git a/tools/include/linux/hashtable.h b/tools/include/linux/hashtable.h
1084 +index c65cc0aa2659..251eabf2a05e 100644
1085 +--- a/tools/include/linux/hashtable.h
1086 ++++ b/tools/include/linux/hashtable.h
1087 +@@ -13,10 +13,6 @@
1088 + #include <linux/hash.h>
1089 + #include <linux/log2.h>
1090 +
1091 +-#ifndef ARRAY_SIZE
1092 +-#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
1093 +-#endif
1094 +-
1095 + #define DEFINE_HASHTABLE(name, bits) \
1096 + struct hlist_head name[1 << (bits)] = \
1097 + { [0 ... ((1 << (bits)) - 1)] = HLIST_HEAD_INIT }
1098 +diff --git a/tools/include/linux/kernel.h b/tools/include/linux/kernel.h
1099 +index 28607db02bd3..73ccc48126bb 100644
1100 +--- a/tools/include/linux/kernel.h
1101 ++++ b/tools/include/linux/kernel.h
1102 +@@ -4,6 +4,11 @@
1103 + #include <stdarg.h>
1104 + #include <stddef.h>
1105 + #include <assert.h>
1106 ++#include <linux/compiler.h>
1107 ++
1108 ++#ifndef UINT_MAX
1109 ++#define UINT_MAX (~0U)
1110 ++#endif
1111 +
1112 + #define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
1113 +
1114 +@@ -72,6 +77,8 @@
1115 + int vscnprintf(char *buf, size_t size, const char *fmt, va_list args);
1116 + int scnprintf(char * buf, size_t size, const char * fmt, ...);
1117 +
1118 ++#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) + __must_be_array(arr))
1119 ++
1120 + /*
1121 + * This looks more complex than it should be. But we need to
1122 + * get the type for the ~ right in round_down (it needs to be
1123 +diff --git a/tools/include/linux/log2.h b/tools/include/linux/log2.h
1124 +index d5677d39c1e4..0325cefc2220 100644
1125 +--- a/tools/include/linux/log2.h
1126 ++++ b/tools/include/linux/log2.h
1127 +@@ -12,6 +12,9 @@
1128 + #ifndef _TOOLS_LINUX_LOG2_H
1129 + #define _TOOLS_LINUX_LOG2_H
1130 +
1131 ++#include <linux/bitops.h>
1132 ++#include <linux/types.h>
1133 ++
1134 + /*
1135 + * non-constant log of base 2 calculators
1136 + * - the arch may override these in asm/bitops.h if they can be implemented
1137 +diff --git a/tools/include/linux/refcount.h b/tools/include/linux/refcount.h
1138 +new file mode 100644
1139 +index 000000000000..a0177c1f55b1
1140 +--- /dev/null
1141 ++++ b/tools/include/linux/refcount.h
1142 +@@ -0,0 +1,151 @@
1143 ++#ifndef _TOOLS_LINUX_REFCOUNT_H
1144 ++#define _TOOLS_LINUX_REFCOUNT_H
1145 ++
1146 ++/*
1147 ++ * Variant of atomic_t specialized for reference counts.
1148 ++ *
1149 ++ * The interface matches the atomic_t interface (to aid in porting) but only
1150 ++ * provides the few functions one should use for reference counting.
1151 ++ *
1152 ++ * It differs in that the counter saturates at UINT_MAX and will not move once
1153 ++ * there. This avoids wrapping the counter and causing 'spurious'
1154 ++ * use-after-free issues.
1155 ++ *
1156 ++ * Memory ordering rules are slightly relaxed wrt regular atomic_t functions
1157 ++ * and provide only what is strictly required for refcounts.
1158 ++ *
1159 ++ * The increments are fully relaxed; these will not provide ordering. The
1160 ++ * rationale is that whatever is used to obtain the object we're increasing the
1161 ++ * reference count on will provide the ordering. For locked data structures,
1162 ++ * its the lock acquire, for RCU/lockless data structures its the dependent
1163 ++ * load.
1164 ++ *
1165 ++ * Do note that inc_not_zero() provides a control dependency which will order
1166 ++ * future stores against the inc, this ensures we'll never modify the object
1167 ++ * if we did not in fact acquire a reference.
1168 ++ *
1169 ++ * The decrements will provide release order, such that all the prior loads and
1170 ++ * stores will be issued before, it also provides a control dependency, which
1171 ++ * will order us against the subsequent free().
1172 ++ *
1173 ++ * The control dependency is against the load of the cmpxchg (ll/sc) that
1174 ++ * succeeded. This means the stores aren't fully ordered, but this is fine
1175 ++ * because the 1->0 transition indicates no concurrency.
1176 ++ *
1177 ++ * Note that the allocator is responsible for ordering things between free()
1178 ++ * and alloc().
1179 ++ *
1180 ++ */
1181 ++
1182 ++#include <linux/atomic.h>
1183 ++#include <linux/kernel.h>
1184 ++
1185 ++#ifdef NDEBUG
1186 ++#define REFCOUNT_WARN(cond, str) (void)(cond)
1187 ++#define __refcount_check
1188 ++#else
1189 ++#define REFCOUNT_WARN(cond, str) BUG_ON(cond)
1190 ++#define __refcount_check __must_check
1191 ++#endif
1192 ++
1193 ++typedef struct refcount_struct {
1194 ++ atomic_t refs;
1195 ++} refcount_t;
1196 ++
1197 ++#define REFCOUNT_INIT(n) { .refs = ATOMIC_INIT(n), }
1198 ++
1199 ++static inline void refcount_set(refcount_t *r, unsigned int n)
1200 ++{
1201 ++ atomic_set(&r->refs, n);
1202 ++}
1203 ++
1204 ++static inline unsigned int refcount_read(const refcount_t *r)
1205 ++{
1206 ++ return atomic_read(&r->refs);
1207 ++}
1208 ++
1209 ++/*
1210 ++ * Similar to atomic_inc_not_zero(), will saturate at UINT_MAX and WARN.
1211 ++ *
1212 ++ * Provides no memory ordering, it is assumed the caller has guaranteed the
1213 ++ * object memory to be stable (RCU, etc.). It does provide a control dependency
1214 ++ * and thereby orders future stores. See the comment on top.
1215 ++ */
1216 ++static inline __refcount_check
1217 ++bool refcount_inc_not_zero(refcount_t *r)
1218 ++{
1219 ++ unsigned int old, new, val = atomic_read(&r->refs);
1220 ++
1221 ++ for (;;) {
1222 ++ new = val + 1;
1223 ++
1224 ++ if (!val)
1225 ++ return false;
1226 ++
1227 ++ if (unlikely(!new))
1228 ++ return true;
1229 ++
1230 ++ old = atomic_cmpxchg_relaxed(&r->refs, val, new);
1231 ++ if (old == val)
1232 ++ break;
1233 ++
1234 ++ val = old;
1235 ++ }
1236 ++
1237 ++ REFCOUNT_WARN(new == UINT_MAX, "refcount_t: saturated; leaking memory.\n");
1238 ++
1239 ++ return true;
1240 ++}
1241 ++
1242 ++/*
1243 ++ * Similar to atomic_inc(), will saturate at UINT_MAX and WARN.
1244 ++ *
1245 ++ * Provides no memory ordering, it is assumed the caller already has a
1246 ++ * reference on the object, will WARN when this is not so.
1247 ++ */
1248 ++static inline void refcount_inc(refcount_t *r)
1249 ++{
1250 ++ REFCOUNT_WARN(!refcount_inc_not_zero(r), "refcount_t: increment on 0; use-after-free.\n");
1251 ++}
1252 ++
1253 ++/*
1254 ++ * Similar to atomic_dec_and_test(), it will WARN on underflow and fail to
1255 ++ * decrement when saturated at UINT_MAX.
1256 ++ *
1257 ++ * Provides release memory ordering, such that prior loads and stores are done
1258 ++ * before, and provides a control dependency such that free() must come after.
1259 ++ * See the comment on top.
1260 ++ */
1261 ++static inline __refcount_check
1262 ++bool refcount_sub_and_test(unsigned int i, refcount_t *r)
1263 ++{
1264 ++ unsigned int old, new, val = atomic_read(&r->refs);
1265 ++
1266 ++ for (;;) {
1267 ++ if (unlikely(val == UINT_MAX))
1268 ++ return false;
1269 ++
1270 ++ new = val - i;
1271 ++ if (new > val) {
1272 ++ REFCOUNT_WARN(new > val, "refcount_t: underflow; use-after-free.\n");
1273 ++ return false;
1274 ++ }
1275 ++
1276 ++ old = atomic_cmpxchg_release(&r->refs, val, new);
1277 ++ if (old == val)
1278 ++ break;
1279 ++
1280 ++ val = old;
1281 ++ }
1282 ++
1283 ++ return !new;
1284 ++}
1285 ++
1286 ++static inline __refcount_check
1287 ++bool refcount_dec_and_test(refcount_t *r)
1288 ++{
1289 ++ return refcount_sub_and_test(1, r);
1290 ++}
1291 ++
1292 ++
1293 ++#endif /* _ATOMIC_LINUX_REFCOUNT_H */
1294 +diff --git a/tools/include/linux/spinlock.h b/tools/include/linux/spinlock.h
1295 +new file mode 100644
1296 +index 000000000000..58397dcb19d6
1297 +--- /dev/null
1298 ++++ b/tools/include/linux/spinlock.h
1299 +@@ -0,0 +1,5 @@
1300 ++#define spinlock_t pthread_mutex_t
1301 ++#define DEFINE_SPINLOCK(x) pthread_mutex_t x = PTHREAD_MUTEX_INITIALIZER;
1302 ++
1303 ++#define spin_lock_irqsave(x, f) (void)f, pthread_mutex_lock(x)
1304 ++#define spin_unlock_irqrestore(x, f) (void)f, pthread_mutex_unlock(x)
1305 +diff --git a/tools/include/linux/types.h b/tools/include/linux/types.h
1306 +index 8ebf6278b2ef..77a28a26a670 100644
1307 +--- a/tools/include/linux/types.h
1308 ++++ b/tools/include/linux/types.h
1309 +@@ -7,6 +7,7 @@
1310 +
1311 + #define __SANE_USERSPACE_TYPES__ /* For PPC64, to get LL64 types */
1312 + #include <asm/types.h>
1313 ++#include <asm/posix_types.h>
1314 +
1315 + struct page;
1316 + struct kmem_cache;
1317 +@@ -42,11 +43,7 @@ typedef __s8 s8;
1318 + #else
1319 + #define __bitwise__
1320 + #endif
1321 +-#ifdef __CHECK_ENDIAN__
1322 + #define __bitwise __bitwise__
1323 +-#else
1324 +-#define __bitwise
1325 +-#endif
1326 +
1327 + #define __force
1328 + #define __user
1329 +diff --git a/tools/include/uapi/asm-generic/mman-common.h b/tools/include/uapi/asm-generic/mman-common.h
1330 +index 58274382a616..8c27db0c5c08 100644
1331 +--- a/tools/include/uapi/asm-generic/mman-common.h
1332 ++++ b/tools/include/uapi/asm-generic/mman-common.h
1333 +@@ -72,4 +72,9 @@
1334 + #define MAP_HUGE_SHIFT 26
1335 + #define MAP_HUGE_MASK 0x3f
1336 +
1337 ++#define PKEY_DISABLE_ACCESS 0x1
1338 ++#define PKEY_DISABLE_WRITE 0x2
1339 ++#define PKEY_ACCESS_MASK (PKEY_DISABLE_ACCESS |\
1340 ++ PKEY_DISABLE_WRITE)
1341 ++
1342 + #endif /* __ASM_GENERIC_MMAN_COMMON_H */
1343 +diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h
1344 +index 9e5fc168c8a3..f09c70b97eca 100644
1345 +--- a/tools/include/uapi/linux/bpf.h
1346 ++++ b/tools/include/uapi/linux/bpf.h
1347 +@@ -95,6 +95,7 @@ enum bpf_prog_type {
1348 + BPF_PROG_TYPE_SCHED_ACT,
1349 + BPF_PROG_TYPE_TRACEPOINT,
1350 + BPF_PROG_TYPE_XDP,
1351 ++ BPF_PROG_TYPE_PERF_EVENT,
1352 + };
1353 +
1354 + #define BPF_PSEUDO_MAP_FD 1
1355 +@@ -375,6 +376,56 @@ enum bpf_func_id {
1356 + */
1357 + BPF_FUNC_probe_write_user,
1358 +
1359 ++ /**
1360 ++ * bpf_current_task_under_cgroup(map, index) - Check cgroup2 membership of current task
1361 ++ * @map: pointer to bpf_map in BPF_MAP_TYPE_CGROUP_ARRAY type
1362 ++ * @index: index of the cgroup in the bpf_map
1363 ++ * Return:
1364 ++ * == 0 current failed the cgroup2 descendant test
1365 ++ * == 1 current succeeded the cgroup2 descendant test
1366 ++ * < 0 error
1367 ++ */
1368 ++ BPF_FUNC_current_task_under_cgroup,
1369 ++
1370 ++ /**
1371 ++ * bpf_skb_change_tail(skb, len, flags)
1372 ++ * The helper will resize the skb to the given new size,
1373 ++ * to be used f.e. with control messages.
1374 ++ * @skb: pointer to skb
1375 ++ * @len: new skb length
1376 ++ * @flags: reserved
1377 ++ * Return: 0 on success or negative error
1378 ++ */
1379 ++ BPF_FUNC_skb_change_tail,
1380 ++
1381 ++ /**
1382 ++ * bpf_skb_pull_data(skb, len)
1383 ++ * The helper will pull in non-linear data in case the
1384 ++ * skb is non-linear and not all of len are part of the
1385 ++ * linear section. Only needed for read/write with direct
1386 ++ * packet access.
1387 ++ * @skb: pointer to skb
1388 ++ * @len: len to make read/writeable
1389 ++ * Return: 0 on success or negative error
1390 ++ */
1391 ++ BPF_FUNC_skb_pull_data,
1392 ++
1393 ++ /**
1394 ++ * bpf_csum_update(skb, csum)
1395 ++ * Adds csum into skb->csum in case of CHECKSUM_COMPLETE.
1396 ++ * @skb: pointer to skb
1397 ++ * @csum: csum to add
1398 ++ * Return: csum on success or negative error
1399 ++ */
1400 ++ BPF_FUNC_csum_update,
1401 ++
1402 ++ /**
1403 ++ * bpf_set_hash_invalid(skb)
1404 ++ * Invalidate current skb>hash.
1405 ++ * @skb: pointer to skb
1406 ++ */
1407 ++ BPF_FUNC_set_hash_invalid,
1408 ++
1409 + __BPF_FUNC_MAX_ID,
1410 + };
1411 +
1412 +diff --git a/tools/include/uapi/linux/fcntl.h b/tools/include/uapi/linux/fcntl.h
1413 +new file mode 100644
1414 +index 000000000000..beed138bd359
1415 +--- /dev/null
1416 ++++ b/tools/include/uapi/linux/fcntl.h
1417 +@@ -0,0 +1,67 @@
1418 ++#ifndef _UAPI_LINUX_FCNTL_H
1419 ++#define _UAPI_LINUX_FCNTL_H
1420 ++
1421 ++#include <asm/fcntl.h>
1422 ++
1423 ++#define F_SETLEASE (F_LINUX_SPECIFIC_BASE + 0)
1424 ++#define F_GETLEASE (F_LINUX_SPECIFIC_BASE + 1)
1425 ++
1426 ++/*
1427 ++ * Cancel a blocking posix lock; internal use only until we expose an
1428 ++ * asynchronous lock api to userspace:
1429 ++ */
1430 ++#define F_CANCELLK (F_LINUX_SPECIFIC_BASE + 5)
1431 ++
1432 ++/* Create a file descriptor with FD_CLOEXEC set. */
1433 ++#define F_DUPFD_CLOEXEC (F_LINUX_SPECIFIC_BASE + 6)
1434 ++
1435 ++/*
1436 ++ * Request nofications on a directory.
1437 ++ * See below for events that may be notified.
1438 ++ */
1439 ++#define F_NOTIFY (F_LINUX_SPECIFIC_BASE+2)
1440 ++
1441 ++/*
1442 ++ * Set and get of pipe page size array
1443 ++ */
1444 ++#define F_SETPIPE_SZ (F_LINUX_SPECIFIC_BASE + 7)
1445 ++#define F_GETPIPE_SZ (F_LINUX_SPECIFIC_BASE + 8)
1446 ++
1447 ++/*
1448 ++ * Set/Get seals
1449 ++ */
1450 ++#define F_ADD_SEALS (F_LINUX_SPECIFIC_BASE + 9)
1451 ++#define F_GET_SEALS (F_LINUX_SPECIFIC_BASE + 10)
1452 ++
1453 ++/*
1454 ++ * Types of seals
1455 ++ */
1456 ++#define F_SEAL_SEAL 0x0001 /* prevent further seals from being set */
1457 ++#define F_SEAL_SHRINK 0x0002 /* prevent file from shrinking */
1458 ++#define F_SEAL_GROW 0x0004 /* prevent file from growing */
1459 ++#define F_SEAL_WRITE 0x0008 /* prevent writes */
1460 ++/* (1U << 31) is reserved for signed error codes */
1461 ++
1462 ++/*
1463 ++ * Types of directory notifications that may be requested.
1464 ++ */
1465 ++#define DN_ACCESS 0x00000001 /* File accessed */
1466 ++#define DN_MODIFY 0x00000002 /* File modified */
1467 ++#define DN_CREATE 0x00000004 /* File created */
1468 ++#define DN_DELETE 0x00000008 /* File removed */
1469 ++#define DN_RENAME 0x00000010 /* File renamed */
1470 ++#define DN_ATTRIB 0x00000020 /* File changed attibutes */
1471 ++#define DN_MULTISHOT 0x80000000 /* Don't remove notifier */
1472 ++
1473 ++#define AT_FDCWD -100 /* Special value used to indicate
1474 ++ openat should use the current
1475 ++ working directory. */
1476 ++#define AT_SYMLINK_NOFOLLOW 0x100 /* Do not follow symbolic links. */
1477 ++#define AT_REMOVEDIR 0x200 /* Remove directory instead of
1478 ++ unlinking file. */
1479 ++#define AT_SYMLINK_FOLLOW 0x400 /* Follow symbolic links. */
1480 ++#define AT_NO_AUTOMOUNT 0x800 /* Suppress terminal automount traversal */
1481 ++#define AT_EMPTY_PATH 0x1000 /* Allow empty relative pathname */
1482 ++
1483 ++
1484 ++#endif /* _UAPI_LINUX_FCNTL_H */
1485 +diff --git a/tools/include/uapi/linux/stat.h b/tools/include/uapi/linux/stat.h
1486 +new file mode 100644
1487 +index 000000000000..7fec7e36d921
1488 +--- /dev/null
1489 ++++ b/tools/include/uapi/linux/stat.h
1490 +@@ -0,0 +1,45 @@
1491 ++#ifndef _UAPI_LINUX_STAT_H
1492 ++#define _UAPI_LINUX_STAT_H
1493 ++
1494 ++
1495 ++#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2)
1496 ++
1497 ++#define S_IFMT 00170000
1498 ++#define S_IFSOCK 0140000
1499 ++#define S_IFLNK 0120000
1500 ++#define S_IFREG 0100000
1501 ++#define S_IFBLK 0060000
1502 ++#define S_IFDIR 0040000
1503 ++#define S_IFCHR 0020000
1504 ++#define S_IFIFO 0010000
1505 ++#define S_ISUID 0004000
1506 ++#define S_ISGID 0002000
1507 ++#define S_ISVTX 0001000
1508 ++
1509 ++#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
1510 ++#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
1511 ++#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
1512 ++#define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
1513 ++#define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
1514 ++#define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
1515 ++#define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)
1516 ++
1517 ++#define S_IRWXU 00700
1518 ++#define S_IRUSR 00400
1519 ++#define S_IWUSR 00200
1520 ++#define S_IXUSR 00100
1521 ++
1522 ++#define S_IRWXG 00070
1523 ++#define S_IRGRP 00040
1524 ++#define S_IWGRP 00020
1525 ++#define S_IXGRP 00010
1526 ++
1527 ++#define S_IRWXO 00007
1528 ++#define S_IROTH 00004
1529 ++#define S_IWOTH 00002
1530 ++#define S_IXOTH 00001
1531 ++
1532 ++#endif
1533 ++
1534 ++
1535 ++#endif /* _UAPI_LINUX_STAT_H */
1536 +diff --git a/tools/lib/find_bit.c b/tools/lib/find_bit.c
1537 +index 9122a9e80046..6d8b8f22cf55 100644
1538 +--- a/tools/lib/find_bit.c
1539 ++++ b/tools/lib/find_bit.c
1540 +@@ -82,3 +82,28 @@ unsigned long find_first_bit(const unsigned long *addr, unsigned long size)
1541 + return size;
1542 + }
1543 + #endif
1544 ++
1545 ++#ifndef find_first_zero_bit
1546 ++/*
1547 ++ * Find the first cleared bit in a memory region.
1548 ++ */
1549 ++unsigned long find_first_zero_bit(const unsigned long *addr, unsigned long size)
1550 ++{
1551 ++ unsigned long idx;
1552 ++
1553 ++ for (idx = 0; idx * BITS_PER_LONG < size; idx++) {
1554 ++ if (addr[idx] != ~0UL)
1555 ++ return min(idx * BITS_PER_LONG + ffz(addr[idx]), size);
1556 ++ }
1557 ++
1558 ++ return size;
1559 ++}
1560 ++#endif
1561 ++
1562 ++#ifndef find_next_zero_bit
1563 ++unsigned long find_next_zero_bit(const unsigned long *addr, unsigned long size,
1564 ++ unsigned long offset)
1565 ++{
1566 ++ return _find_next_bit(addr, size, offset, ~0UL);
1567 ++}
1568 ++#endif
1569 +diff --git a/tools/objtool/Build b/tools/objtool/Build
1570 +index d6cdece5e58b..749becdf5b90 100644
1571 +--- a/tools/objtool/Build
1572 ++++ b/tools/objtool/Build
1573 +@@ -1,5 +1,9 @@
1574 + objtool-y += arch/$(SRCARCH)/
1575 + objtool-y += builtin-check.o
1576 ++objtool-y += builtin-orc.o
1577 ++objtool-y += check.o
1578 ++objtool-y += orc_gen.o
1579 ++objtool-y += orc_dump.o
1580 + objtool-y += elf.o
1581 + objtool-y += special.o
1582 + objtool-y += objtool.o
1583 +diff --git a/tools/objtool/Documentation/stack-validation.txt b/tools/objtool/Documentation/stack-validation.txt
1584 +index 55a60d331f47..3995735a878f 100644
1585 +--- a/tools/objtool/Documentation/stack-validation.txt
1586 ++++ b/tools/objtool/Documentation/stack-validation.txt
1587 +@@ -11,9 +11,6 @@ analyzes every .o file and ensures the validity of its stack metadata.
1588 + It enforces a set of rules on asm code and C inline assembly code so
1589 + that stack traces can be reliable.
1590 +
1591 +-Currently it only checks frame pointer usage, but there are plans to add
1592 +-CFI validation for C files and CFI generation for asm files.
1593 +-
1594 + For each function, it recursively follows all possible code paths and
1595 + validates the correct frame pointer state at each instruction.
1596 +
1597 +@@ -23,6 +20,10 @@ alternative execution paths to a given instruction (or set of
1598 + instructions). Similarly, it knows how to follow switch statements, for
1599 + which gcc sometimes uses jump tables.
1600 +
1601 ++(Objtool also has an 'orc generate' subcommand which generates debuginfo
1602 ++for the ORC unwinder. See Documentation/x86/orc-unwinder.txt in the
1603 ++kernel tree for more details.)
1604 ++
1605 +
1606 + Why do we need stack metadata validation?
1607 + -----------------------------------------
1608 +@@ -93,62 +94,24 @@ a) More reliable stack traces for frame pointer enabled kernels
1609 + or at the very end of the function after the stack frame has been
1610 + destroyed. This is an inherent limitation of frame pointers.
1611 +
1612 +-b) 100% reliable stack traces for DWARF enabled kernels
1613 +-
1614 +- (NOTE: This is not yet implemented)
1615 +-
1616 +- As an alternative to frame pointers, DWARF Call Frame Information
1617 +- (CFI) metadata can be used to walk the stack. Unlike frame pointers,
1618 +- CFI metadata is out of band. So it doesn't affect runtime
1619 +- performance and it can be reliable even when interrupts or exceptions
1620 +- are involved.
1621 +-
1622 +- For C code, gcc automatically generates DWARF CFI metadata. But for
1623 +- asm code, generating CFI is a tedious manual approach which requires
1624 +- manually placed .cfi assembler macros to be scattered throughout the
1625 +- code. It's clumsy and very easy to get wrong, and it makes the real
1626 +- code harder to read.
1627 +-
1628 +- Stacktool will improve this situation in several ways. For code
1629 +- which already has CFI annotations, it will validate them. For code
1630 +- which doesn't have CFI annotations, it will generate them. So an
1631 +- architecture can opt to strip out all the manual .cfi annotations
1632 +- from their asm code and have objtool generate them instead.
1633 ++b) ORC (Oops Rewind Capability) unwind table generation
1634 +
1635 +- We might also add a runtime stack validation debug option where we
1636 +- periodically walk the stack from schedule() and/or an NMI to ensure
1637 +- that the stack metadata is sane and that we reach the bottom of the
1638 +- stack.
1639 ++ An alternative to frame pointers and DWARF, ORC unwind data can be
1640 ++ used to walk the stack. Unlike frame pointers, ORC data is out of
1641 ++ band. So it doesn't affect runtime performance and it can be
1642 ++ reliable even when interrupts or exceptions are involved.
1643 +
1644 +- So the benefit of objtool here will be that external tooling should
1645 +- always show perfect stack traces. And the same will be true for
1646 +- kernel warning/oops traces if the architecture has a runtime DWARF
1647 +- unwinder.
1648 ++ For more details, see Documentation/x86/orc-unwinder.txt.
1649 +
1650 + c) Higher live patching compatibility rate
1651 +
1652 +- (NOTE: This is not yet implemented)
1653 +-
1654 +- Currently with CONFIG_LIVEPATCH there's a basic live patching
1655 +- framework which is safe for roughly 85-90% of "security" fixes. But
1656 +- patches can't have complex features like function dependency or
1657 +- prototype changes, or data structure changes.
1658 +-
1659 +- There's a strong need to support patches which have the more complex
1660 +- features so that the patch compatibility rate for security fixes can
1661 +- eventually approach something resembling 100%. To achieve that, a
1662 +- "consistency model" is needed, which allows tasks to be safely
1663 +- transitioned from an unpatched state to a patched state.
1664 +-
1665 +- One of the key requirements of the currently proposed livepatch
1666 +- consistency model [*] is that it needs to walk the stack of each
1667 +- sleeping task to determine if it can be transitioned to the patched
1668 +- state. If objtool can ensure that stack traces are reliable, this
1669 +- consistency model can be used and the live patching compatibility
1670 +- rate can be improved significantly.
1671 +-
1672 +- [*] https://lkml.kernel.org/r/cover.1423499826.git.jpoimboe@××××××.com
1673 ++ Livepatch has an optional "consistency model", which is needed for
1674 ++ more complex patches. In order for the consistency model to work,
1675 ++ stack traces need to be reliable (or an unreliable condition needs to
1676 ++ be detectable). Objtool makes that possible.
1677 +
1678 ++ For more details, see the livepatch documentation in the Linux kernel
1679 ++ source tree at Documentation/livepatch/livepatch.txt.
1680 +
1681 + Rules
1682 + -----
1683 +@@ -201,80 +164,84 @@ To achieve the validation, objtool enforces the following rules:
1684 + return normally.
1685 +
1686 +
1687 +-Errors in .S files
1688 +-------------------
1689 ++Objtool warnings
1690 ++----------------
1691 ++
1692 ++For asm files, if you're getting an error which doesn't make sense,
1693 ++first make sure that the affected code follows the above rules.
1694 +
1695 +-If you're getting an error in a compiled .S file which you don't
1696 +-understand, first make sure that the affected code follows the above
1697 +-rules.
1698 ++For C files, the common culprits are inline asm statements and calls to
1699 ++"noreturn" functions. See below for more details.
1700 ++
1701 ++Another possible cause for errors in C code is if the Makefile removes
1702 ++-fno-omit-frame-pointer or adds -fomit-frame-pointer to the gcc options.
1703 +
1704 + Here are some examples of common warnings reported by objtool, what
1705 + they mean, and suggestions for how to fix them.
1706 +
1707 +
1708 +-1. asm_file.o: warning: objtool: func()+0x128: call without frame pointer save/setup
1709 ++1. file.o: warning: objtool: func()+0x128: call without frame pointer save/setup
1710 +
1711 + The func() function made a function call without first saving and/or
1712 +- updating the frame pointer.
1713 +-
1714 +- If func() is indeed a callable function, add proper frame pointer
1715 +- logic using the FRAME_BEGIN and FRAME_END macros. Otherwise, remove
1716 +- its ELF function annotation by changing ENDPROC to END.
1717 +-
1718 +- If you're getting this error in a .c file, see the "Errors in .c
1719 +- files" section.
1720 ++ updating the frame pointer, and CONFIG_FRAME_POINTER is enabled.
1721 +
1722 ++ If the error is for an asm file, and func() is indeed a callable
1723 ++ function, add proper frame pointer logic using the FRAME_BEGIN and
1724 ++ FRAME_END macros. Otherwise, if it's not a callable function, remove
1725 ++ its ELF function annotation by changing ENDPROC to END, and instead
1726 ++ use the manual unwind hint macros in asm/unwind_hints.h.
1727 +
1728 +-2. asm_file.o: warning: objtool: .text+0x53: return instruction outside of a callable function
1729 ++ If it's a GCC-compiled .c file, the error may be because the function
1730 ++ uses an inline asm() statement which has a "call" instruction. An
1731 ++ asm() statement with a call instruction must declare the use of the
1732 ++ stack pointer in its output operand. On x86_64, this means adding
1733 ++ the ASM_CALL_CONSTRAINT as an output constraint:
1734 +
1735 +- A return instruction was detected, but objtool couldn't find a way
1736 +- for a callable function to reach the instruction.
1737 ++ asm volatile("call func" : ASM_CALL_CONSTRAINT);
1738 +
1739 +- If the return instruction is inside (or reachable from) a callable
1740 +- function, the function needs to be annotated with the ENTRY/ENDPROC
1741 +- macros.
1742 ++ Otherwise the stack frame may not get created before the call.
1743 +
1744 +- If you _really_ need a return instruction outside of a function, and
1745 +- are 100% sure that it won't affect stack traces, you can tell
1746 +- objtool to ignore it. See the "Adding exceptions" section below.
1747 +
1748 ++2. file.o: warning: objtool: .text+0x53: unreachable instruction
1749 +
1750 +-3. asm_file.o: warning: objtool: func()+0x9: function has unreachable instruction
1751 ++ Objtool couldn't find a code path to reach the instruction.
1752 +
1753 +- The instruction lives inside of a callable function, but there's no
1754 +- possible control flow path from the beginning of the function to the
1755 +- instruction.
1756 ++ If the error is for an asm file, and the instruction is inside (or
1757 ++ reachable from) a callable function, the function should be annotated
1758 ++ with the ENTRY/ENDPROC macros (ENDPROC is the important one).
1759 ++ Otherwise, the code should probably be annotated with the unwind hint
1760 ++ macros in asm/unwind_hints.h so objtool and the unwinder can know the
1761 ++ stack state associated with the code.
1762 +
1763 +- If the instruction is actually needed, and it's actually in a
1764 +- callable function, ensure that its function is properly annotated
1765 +- with ENTRY/ENDPROC.
1766 ++ If you're 100% sure the code won't affect stack traces, or if you're
1767 ++ a just a bad person, you can tell objtool to ignore it. See the
1768 ++ "Adding exceptions" section below.
1769 +
1770 + If it's not actually in a callable function (e.g. kernel entry code),
1771 + change ENDPROC to END.
1772 +
1773 +
1774 +-4. asm_file.o: warning: objtool: func(): can't find starting instruction
1775 ++4. file.o: warning: objtool: func(): can't find starting instruction
1776 + or
1777 +- asm_file.o: warning: objtool: func()+0x11dd: can't decode instruction
1778 ++ file.o: warning: objtool: func()+0x11dd: can't decode instruction
1779 +
1780 +- Did you put data in a text section? If so, that can confuse
1781 ++ Does the file have data in a text section? If so, that can confuse
1782 + objtool's instruction decoder. Move the data to a more appropriate
1783 + section like .data or .rodata.
1784 +
1785 +
1786 +-5. asm_file.o: warning: objtool: func()+0x6: kernel entry/exit from callable instruction
1787 +-
1788 +- This is a kernel entry/exit instruction like sysenter or sysret.
1789 +- Such instructions aren't allowed in a callable function, and are most
1790 +- likely part of the kernel entry code.
1791 ++5. file.o: warning: objtool: func()+0x6: unsupported instruction in callable function
1792 +
1793 +- If the instruction isn't actually in a callable function, change
1794 +- ENDPROC to END.
1795 ++ This is a kernel entry/exit instruction like sysenter or iret. Such
1796 ++ instructions aren't allowed in a callable function, and are most
1797 ++ likely part of the kernel entry code. They should usually not have
1798 ++ the callable function annotation (ENDPROC) and should always be
1799 ++ annotated with the unwind hint macros in asm/unwind_hints.h.
1800 +
1801 +
1802 +-6. asm_file.o: warning: objtool: func()+0x26: sibling call from callable instruction with changed frame pointer
1803 ++6. file.o: warning: objtool: func()+0x26: sibling call from callable instruction with modified stack frame
1804 +
1805 +- This is a dynamic jump or a jump to an undefined symbol. Stacktool
1806 ++ This is a dynamic jump or a jump to an undefined symbol. Objtool
1807 + assumed it's a sibling call and detected that the frame pointer
1808 + wasn't first restored to its original state.
1809 +
1810 +@@ -282,24 +249,28 @@ they mean, and suggestions for how to fix them.
1811 + destination code to the local file.
1812 +
1813 + If the instruction is not actually in a callable function (e.g.
1814 +- kernel entry code), change ENDPROC to END.
1815 ++ kernel entry code), change ENDPROC to END and annotate manually with
1816 ++ the unwind hint macros in asm/unwind_hints.h.
1817 +
1818 +
1819 +-7. asm_file: warning: objtool: func()+0x5c: frame pointer state mismatch
1820 ++7. file: warning: objtool: func()+0x5c: stack state mismatch
1821 +
1822 + The instruction's frame pointer state is inconsistent, depending on
1823 + which execution path was taken to reach the instruction.
1824 +
1825 +- Make sure the function pushes and sets up the frame pointer (for
1826 +- x86_64, this means rbp) at the beginning of the function and pops it
1827 +- at the end of the function. Also make sure that no other code in the
1828 +- function touches the frame pointer.
1829 ++ Make sure that, when CONFIG_FRAME_POINTER is enabled, the function
1830 ++ pushes and sets up the frame pointer (for x86_64, this means rbp) at
1831 ++ the beginning of the function and pops it at the end of the function.
1832 ++ Also make sure that no other code in the function touches the frame
1833 ++ pointer.
1834 +
1835 ++ Another possibility is that the code has some asm or inline asm which
1836 ++ does some unusual things to the stack or the frame pointer. In such
1837 ++ cases it's probably appropriate to use the unwind hint macros in
1838 ++ asm/unwind_hints.h.
1839 +
1840 +-Errors in .c files
1841 +-------------------
1842 +
1843 +-1. c_file.o: warning: objtool: funcA() falls through to next function funcB()
1844 ++8. file.o: warning: objtool: funcA() falls through to next function funcB()
1845 +
1846 + This means that funcA() doesn't end with a return instruction or an
1847 + unconditional jump, and that objtool has determined that the function
1848 +@@ -318,22 +289,6 @@ Errors in .c files
1849 + might be corrupt due to a gcc bug. For more details, see:
1850 + https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70646
1851 +
1852 +-2. If you're getting any other objtool error in a compiled .c file, it
1853 +- may be because the file uses an asm() statement which has a "call"
1854 +- instruction. An asm() statement with a call instruction must declare
1855 +- the use of the stack pointer in its output operand. For example, on
1856 +- x86_64:
1857 +-
1858 +- register void *__sp asm("rsp");
1859 +- asm volatile("call func" : "+r" (__sp));
1860 +-
1861 +- Otherwise the stack frame may not get created before the call.
1862 +-
1863 +-3. Another possible cause for errors in C code is if the Makefile removes
1864 +- -fno-omit-frame-pointer or adds -fomit-frame-pointer to the gcc options.
1865 +-
1866 +-Also see the above section for .S file errors for more information what
1867 +-the individual error messages mean.
1868 +
1869 + If the error doesn't seem to make sense, it could be a bug in objtool.
1870 + Feel free to ask the objtool maintainer for help.
1871 +diff --git a/tools/objtool/Makefile b/tools/objtool/Makefile
1872 +index 041b493ad3ab..e6acc281dd37 100644
1873 +--- a/tools/objtool/Makefile
1874 ++++ b/tools/objtool/Makefile
1875 +@@ -1,3 +1,4 @@
1876 ++# SPDX-License-Identifier: GPL-2.0
1877 + include ../scripts/Makefile.include
1878 + include ../scripts/Makefile.arch
1879 +
1880 +@@ -6,17 +7,19 @@ ARCH := x86
1881 + endif
1882 +
1883 + # always use the host compiler
1884 +-CC = gcc
1885 +-LD = ld
1886 +-AR = ar
1887 ++HOSTCC ?= gcc
1888 ++HOSTLD ?= ld
1889 ++CC = $(HOSTCC)
1890 ++LD = $(HOSTLD)
1891 ++AR = ar
1892 +
1893 + ifeq ($(srctree),)
1894 +-srctree := $(patsubst %/,%,$(dir $(shell pwd)))
1895 ++srctree := $(patsubst %/,%,$(dir $(CURDIR)))
1896 + srctree := $(patsubst %/,%,$(dir $(srctree)))
1897 + endif
1898 +
1899 + SUBCMD_SRCDIR = $(srctree)/tools/lib/subcmd/
1900 +-LIBSUBCMD_OUTPUT = $(if $(OUTPUT),$(OUTPUT),$(PWD)/)
1901 ++LIBSUBCMD_OUTPUT = $(if $(OUTPUT),$(OUTPUT),$(CURDIR)/)
1902 + LIBSUBCMD = $(LIBSUBCMD_OUTPUT)libsubcmd.a
1903 +
1904 + OBJTOOL := $(OUTPUT)objtool
1905 +@@ -24,8 +27,11 @@ OBJTOOL_IN := $(OBJTOOL)-in.o
1906 +
1907 + all: $(OBJTOOL)
1908 +
1909 +-INCLUDES := -I$(srctree)/tools/include -I$(srctree)/tools/arch/$(HOSTARCH)/include/uapi
1910 +-CFLAGS += -Wall -Werror $(EXTRA_WARNINGS) -fomit-frame-pointer -O2 -g $(INCLUDES)
1911 ++INCLUDES := -I$(srctree)/tools/include \
1912 ++ -I$(srctree)/tools/arch/$(HOSTARCH)/include/uapi \
1913 ++ -I$(srctree)/tools/objtool/arch/$(ARCH)/include
1914 ++WARNINGS := $(EXTRA_WARNINGS) -Wno-switch-default -Wno-switch-enum -Wno-packed
1915 ++CFLAGS += -Wall -Werror $(WARNINGS) -fomit-frame-pointer -O2 -g $(INCLUDES)
1916 + LDFLAGS += -lelf $(LIBSUBCMD)
1917 +
1918 + # Allow old libelf to be used:
1919 +@@ -39,19 +45,8 @@ include $(srctree)/tools/build/Makefile.include
1920 + $(OBJTOOL_IN): fixdep FORCE
1921 + @$(MAKE) $(build)=objtool
1922 +
1923 +-# Busybox's diff doesn't have -I, avoid warning in that case
1924 +-#
1925 + $(OBJTOOL): $(LIBSUBCMD) $(OBJTOOL_IN)
1926 +- @(diff -I 2>&1 | grep -q 'option requires an argument' && \
1927 +- test -d ../../kernel -a -d ../../tools -a -d ../objtool && (( \
1928 +- diff -I'^#include' arch/x86/insn/insn.c ../../arch/x86/lib/insn.c >/dev/null && \
1929 +- diff -I'^#include' arch/x86/insn/inat.c ../../arch/x86/lib/inat.c >/dev/null && \
1930 +- diff arch/x86/insn/x86-opcode-map.txt ../../arch/x86/lib/x86-opcode-map.txt >/dev/null && \
1931 +- diff arch/x86/insn/gen-insn-attr-x86.awk ../../arch/x86/tools/gen-insn-attr-x86.awk >/dev/null && \
1932 +- diff -I'^#include' arch/x86/insn/insn.h ../../arch/x86/include/asm/insn.h >/dev/null && \
1933 +- diff -I'^#include' arch/x86/insn/inat.h ../../arch/x86/include/asm/inat.h >/dev/null && \
1934 +- diff -I'^#include' arch/x86/insn/inat_types.h ../../arch/x86/include/asm/inat_types.h >/dev/null) \
1935 +- || echo "warning: objtool: x86 instruction decoder differs from kernel" >&2 )) || true
1936 ++ @$(CONFIG_SHELL) ./sync-check.sh
1937 + $(QUIET_LINK)$(CC) $(OBJTOOL_IN) $(LDFLAGS) -o $@
1938 +
1939 +
1940 +@@ -61,7 +56,7 @@ $(LIBSUBCMD): fixdep FORCE
1941 + clean:
1942 + $(call QUIET_CLEAN, objtool) $(RM) $(OBJTOOL)
1943 + $(Q)find $(OUTPUT) -name '*.o' -delete -o -name '\.*.cmd' -delete -o -name '\.*.d' -delete
1944 +- $(Q)$(RM) $(OUTPUT)arch/x86/insn/inat-tables.c $(OUTPUT)fixdep
1945 ++ $(Q)$(RM) $(OUTPUT)arch/x86/lib/inat-tables.c $(OUTPUT)fixdep
1946 +
1947 + FORCE:
1948 +
1949 +diff --git a/tools/objtool/arch.h b/tools/objtool/arch.h
1950 +index f7350fcedc70..b0d7dc3d71b5 100644
1951 +--- a/tools/objtool/arch.h
1952 ++++ b/tools/objtool/arch.h
1953 +@@ -19,26 +19,64 @@
1954 + #define _ARCH_H
1955 +
1956 + #include <stdbool.h>
1957 ++#include <linux/list.h>
1958 + #include "elf.h"
1959 ++#include "cfi.h"
1960 +
1961 +-#define INSN_FP_SAVE 1
1962 +-#define INSN_FP_SETUP 2
1963 +-#define INSN_FP_RESTORE 3
1964 +-#define INSN_JUMP_CONDITIONAL 4
1965 +-#define INSN_JUMP_UNCONDITIONAL 5
1966 +-#define INSN_JUMP_DYNAMIC 6
1967 +-#define INSN_CALL 7
1968 +-#define INSN_CALL_DYNAMIC 8
1969 +-#define INSN_RETURN 9
1970 +-#define INSN_CONTEXT_SWITCH 10
1971 +-#define INSN_BUG 11
1972 +-#define INSN_NOP 12
1973 +-#define INSN_OTHER 13
1974 ++#define INSN_JUMP_CONDITIONAL 1
1975 ++#define INSN_JUMP_UNCONDITIONAL 2
1976 ++#define INSN_JUMP_DYNAMIC 3
1977 ++#define INSN_CALL 4
1978 ++#define INSN_CALL_DYNAMIC 5
1979 ++#define INSN_RETURN 6
1980 ++#define INSN_CONTEXT_SWITCH 7
1981 ++#define INSN_STACK 8
1982 ++#define INSN_BUG 9
1983 ++#define INSN_NOP 10
1984 ++#define INSN_OTHER 11
1985 + #define INSN_LAST INSN_OTHER
1986 +
1987 ++enum op_dest_type {
1988 ++ OP_DEST_REG,
1989 ++ OP_DEST_REG_INDIRECT,
1990 ++ OP_DEST_MEM,
1991 ++ OP_DEST_PUSH,
1992 ++ OP_DEST_LEAVE,
1993 ++};
1994 ++
1995 ++struct op_dest {
1996 ++ enum op_dest_type type;
1997 ++ unsigned char reg;
1998 ++ int offset;
1999 ++};
2000 ++
2001 ++enum op_src_type {
2002 ++ OP_SRC_REG,
2003 ++ OP_SRC_REG_INDIRECT,
2004 ++ OP_SRC_CONST,
2005 ++ OP_SRC_POP,
2006 ++ OP_SRC_ADD,
2007 ++ OP_SRC_AND,
2008 ++};
2009 ++
2010 ++struct op_src {
2011 ++ enum op_src_type type;
2012 ++ unsigned char reg;
2013 ++ int offset;
2014 ++};
2015 ++
2016 ++struct stack_op {
2017 ++ struct op_dest dest;
2018 ++ struct op_src src;
2019 ++};
2020 ++
2021 ++void arch_initial_func_cfi_state(struct cfi_state *state);
2022 ++
2023 + int arch_decode_instruction(struct elf *elf, struct section *sec,
2024 + unsigned long offset, unsigned int maxlen,
2025 + unsigned int *len, unsigned char *type,
2026 +- unsigned long *displacement);
2027 ++ unsigned long *immediate, struct stack_op *op);
2028 ++
2029 ++bool arch_callee_saved_reg(unsigned char reg);
2030 +
2031 + #endif /* _ARCH_H */
2032 +diff --git a/tools/objtool/arch/x86/Build b/tools/objtool/arch/x86/Build
2033 +index debbdb0b5c43..b998412c017d 100644
2034 +--- a/tools/objtool/arch/x86/Build
2035 ++++ b/tools/objtool/arch/x86/Build
2036 +@@ -1,12 +1,12 @@
2037 + objtool-y += decode.o
2038 +
2039 +-inat_tables_script = arch/x86/insn/gen-insn-attr-x86.awk
2040 +-inat_tables_maps = arch/x86/insn/x86-opcode-map.txt
2041 ++inat_tables_script = arch/x86/tools/gen-insn-attr-x86.awk
2042 ++inat_tables_maps = arch/x86/lib/x86-opcode-map.txt
2043 +
2044 +-$(OUTPUT)arch/x86/insn/inat-tables.c: $(inat_tables_script) $(inat_tables_maps)
2045 ++$(OUTPUT)arch/x86/lib/inat-tables.c: $(inat_tables_script) $(inat_tables_maps)
2046 + $(call rule_mkdir)
2047 + $(Q)$(call echo-cmd,gen)$(AWK) -f $(inat_tables_script) $(inat_tables_maps) > $@
2048 +
2049 +-$(OUTPUT)arch/x86/decode.o: $(OUTPUT)arch/x86/insn/inat-tables.c
2050 ++$(OUTPUT)arch/x86/decode.o: $(OUTPUT)arch/x86/lib/inat-tables.c
2051 +
2052 +-CFLAGS_decode.o += -I$(OUTPUT)arch/x86/insn
2053 ++CFLAGS_decode.o += -I$(OUTPUT)arch/x86/lib
2054 +diff --git a/tools/objtool/arch/x86/decode.c b/tools/objtool/arch/x86/decode.c
2055 +index 039636ffb6c8..540a209b78ab 100644
2056 +--- a/tools/objtool/arch/x86/decode.c
2057 ++++ b/tools/objtool/arch/x86/decode.c
2058 +@@ -19,14 +19,25 @@
2059 + #include <stdlib.h>
2060 +
2061 + #define unlikely(cond) (cond)
2062 +-#include "insn/insn.h"
2063 +-#include "insn/inat.c"
2064 +-#include "insn/insn.c"
2065 ++#include <asm/insn.h>
2066 ++#include "lib/inat.c"
2067 ++#include "lib/insn.c"
2068 +
2069 + #include "../../elf.h"
2070 + #include "../../arch.h"
2071 + #include "../../warn.h"
2072 +
2073 ++static unsigned char op_to_cfi_reg[][2] = {
2074 ++ {CFI_AX, CFI_R8},
2075 ++ {CFI_CX, CFI_R9},
2076 ++ {CFI_DX, CFI_R10},
2077 ++ {CFI_BX, CFI_R11},
2078 ++ {CFI_SP, CFI_R12},
2079 ++ {CFI_BP, CFI_R13},
2080 ++ {CFI_SI, CFI_R14},
2081 ++ {CFI_DI, CFI_R15},
2082 ++};
2083 ++
2084 + static int is_x86_64(struct elf *elf)
2085 + {
2086 + switch (elf->ehdr.e_machine) {
2087 +@@ -40,24 +51,50 @@ static int is_x86_64(struct elf *elf)
2088 + }
2089 + }
2090 +
2091 ++bool arch_callee_saved_reg(unsigned char reg)
2092 ++{
2093 ++ switch (reg) {
2094 ++ case CFI_BP:
2095 ++ case CFI_BX:
2096 ++ case CFI_R12:
2097 ++ case CFI_R13:
2098 ++ case CFI_R14:
2099 ++ case CFI_R15:
2100 ++ return true;
2101 ++
2102 ++ case CFI_AX:
2103 ++ case CFI_CX:
2104 ++ case CFI_DX:
2105 ++ case CFI_SI:
2106 ++ case CFI_DI:
2107 ++ case CFI_SP:
2108 ++ case CFI_R8:
2109 ++ case CFI_R9:
2110 ++ case CFI_R10:
2111 ++ case CFI_R11:
2112 ++ case CFI_RA:
2113 ++ default:
2114 ++ return false;
2115 ++ }
2116 ++}
2117 ++
2118 + int arch_decode_instruction(struct elf *elf, struct section *sec,
2119 + unsigned long offset, unsigned int maxlen,
2120 + unsigned int *len, unsigned char *type,
2121 +- unsigned long *immediate)
2122 ++ unsigned long *immediate, struct stack_op *op)
2123 + {
2124 + struct insn insn;
2125 +- int x86_64;
2126 +- unsigned char op1, op2, ext;
2127 ++ int x86_64, sign;
2128 ++ unsigned char op1, op2, rex = 0, rex_b = 0, rex_r = 0, rex_w = 0,
2129 ++ rex_x = 0, modrm = 0, modrm_mod = 0, modrm_rm = 0,
2130 ++ modrm_reg = 0, sib = 0;
2131 +
2132 + x86_64 = is_x86_64(elf);
2133 + if (x86_64 == -1)
2134 + return -1;
2135 +
2136 +- insn_init(&insn, (void *)(sec->data + offset), maxlen, x86_64);
2137 ++ insn_init(&insn, sec->data->d_buf + offset, maxlen, x86_64);
2138 + insn_get_length(&insn);
2139 +- insn_get_opcode(&insn);
2140 +- insn_get_modrm(&insn);
2141 +- insn_get_immediate(&insn);
2142 +
2143 + if (!insn_complete(&insn)) {
2144 + WARN_FUNC("can't decode instruction", sec, offset);
2145 +@@ -73,70 +110,317 @@ int arch_decode_instruction(struct elf *elf, struct section *sec,
2146 + op1 = insn.opcode.bytes[0];
2147 + op2 = insn.opcode.bytes[1];
2148 +
2149 ++ if (insn.rex_prefix.nbytes) {
2150 ++ rex = insn.rex_prefix.bytes[0];
2151 ++ rex_w = X86_REX_W(rex) >> 3;
2152 ++ rex_r = X86_REX_R(rex) >> 2;
2153 ++ rex_x = X86_REX_X(rex) >> 1;
2154 ++ rex_b = X86_REX_B(rex);
2155 ++ }
2156 ++
2157 ++ if (insn.modrm.nbytes) {
2158 ++ modrm = insn.modrm.bytes[0];
2159 ++ modrm_mod = X86_MODRM_MOD(modrm);
2160 ++ modrm_reg = X86_MODRM_REG(modrm);
2161 ++ modrm_rm = X86_MODRM_RM(modrm);
2162 ++ }
2163 ++
2164 ++ if (insn.sib.nbytes)
2165 ++ sib = insn.sib.bytes[0];
2166 ++
2167 + switch (op1) {
2168 +- case 0x55:
2169 +- if (!insn.rex_prefix.nbytes)
2170 +- /* push rbp */
2171 +- *type = INSN_FP_SAVE;
2172 ++
2173 ++ case 0x1:
2174 ++ case 0x29:
2175 ++ if (rex_w && !rex_b && modrm_mod == 3 && modrm_rm == 4) {
2176 ++
2177 ++ /* add/sub reg, %rsp */
2178 ++ *type = INSN_STACK;
2179 ++ op->src.type = OP_SRC_ADD;
2180 ++ op->src.reg = op_to_cfi_reg[modrm_reg][rex_r];
2181 ++ op->dest.type = OP_DEST_REG;
2182 ++ op->dest.reg = CFI_SP;
2183 ++ }
2184 ++ break;
2185 ++
2186 ++ case 0x50 ... 0x57:
2187 ++
2188 ++ /* push reg */
2189 ++ *type = INSN_STACK;
2190 ++ op->src.type = OP_SRC_REG;
2191 ++ op->src.reg = op_to_cfi_reg[op1 & 0x7][rex_b];
2192 ++ op->dest.type = OP_DEST_PUSH;
2193 ++
2194 ++ break;
2195 ++
2196 ++ case 0x58 ... 0x5f:
2197 ++
2198 ++ /* pop reg */
2199 ++ *type = INSN_STACK;
2200 ++ op->src.type = OP_SRC_POP;
2201 ++ op->dest.type = OP_DEST_REG;
2202 ++ op->dest.reg = op_to_cfi_reg[op1 & 0x7][rex_b];
2203 ++
2204 + break;
2205 +
2206 +- case 0x5d:
2207 +- if (!insn.rex_prefix.nbytes)
2208 +- /* pop rbp */
2209 +- *type = INSN_FP_RESTORE;
2210 ++ case 0x68:
2211 ++ case 0x6a:
2212 ++ /* push immediate */
2213 ++ *type = INSN_STACK;
2214 ++ op->src.type = OP_SRC_CONST;
2215 ++ op->dest.type = OP_DEST_PUSH;
2216 + break;
2217 +
2218 + case 0x70 ... 0x7f:
2219 + *type = INSN_JUMP_CONDITIONAL;
2220 + break;
2221 +
2222 ++ case 0x81:
2223 ++ case 0x83:
2224 ++ if (rex != 0x48)
2225 ++ break;
2226 ++
2227 ++ if (modrm == 0xe4) {
2228 ++ /* and imm, %rsp */
2229 ++ *type = INSN_STACK;
2230 ++ op->src.type = OP_SRC_AND;
2231 ++ op->src.reg = CFI_SP;
2232 ++ op->src.offset = insn.immediate.value;
2233 ++ op->dest.type = OP_DEST_REG;
2234 ++ op->dest.reg = CFI_SP;
2235 ++ break;
2236 ++ }
2237 ++
2238 ++ if (modrm == 0xc4)
2239 ++ sign = 1;
2240 ++ else if (modrm == 0xec)
2241 ++ sign = -1;
2242 ++ else
2243 ++ break;
2244 ++
2245 ++ /* add/sub imm, %rsp */
2246 ++ *type = INSN_STACK;
2247 ++ op->src.type = OP_SRC_ADD;
2248 ++ op->src.reg = CFI_SP;
2249 ++ op->src.offset = insn.immediate.value * sign;
2250 ++ op->dest.type = OP_DEST_REG;
2251 ++ op->dest.reg = CFI_SP;
2252 ++ break;
2253 ++
2254 + case 0x89:
2255 +- if (insn.rex_prefix.nbytes == 1 &&
2256 +- insn.rex_prefix.bytes[0] == 0x48 &&
2257 +- insn.modrm.nbytes && insn.modrm.bytes[0] == 0xe5)
2258 +- /* mov rsp, rbp */
2259 +- *type = INSN_FP_SETUP;
2260 ++ if (rex_w && !rex_r && modrm_mod == 3 && modrm_reg == 4) {
2261 ++
2262 ++ /* mov %rsp, reg */
2263 ++ *type = INSN_STACK;
2264 ++ op->src.type = OP_SRC_REG;
2265 ++ op->src.reg = CFI_SP;
2266 ++ op->dest.type = OP_DEST_REG;
2267 ++ op->dest.reg = op_to_cfi_reg[modrm_rm][rex_b];
2268 ++ break;
2269 ++ }
2270 ++
2271 ++ if (rex_w && !rex_b && modrm_mod == 3 && modrm_rm == 4) {
2272 ++
2273 ++ /* mov reg, %rsp */
2274 ++ *type = INSN_STACK;
2275 ++ op->src.type = OP_SRC_REG;
2276 ++ op->src.reg = op_to_cfi_reg[modrm_reg][rex_r];
2277 ++ op->dest.type = OP_DEST_REG;
2278 ++ op->dest.reg = CFI_SP;
2279 ++ break;
2280 ++ }
2281 ++
2282 ++ /* fallthrough */
2283 ++ case 0x88:
2284 ++ if (!rex_b &&
2285 ++ (modrm_mod == 1 || modrm_mod == 2) && modrm_rm == 5) {
2286 ++
2287 ++ /* mov reg, disp(%rbp) */
2288 ++ *type = INSN_STACK;
2289 ++ op->src.type = OP_SRC_REG;
2290 ++ op->src.reg = op_to_cfi_reg[modrm_reg][rex_r];
2291 ++ op->dest.type = OP_DEST_REG_INDIRECT;
2292 ++ op->dest.reg = CFI_BP;
2293 ++ op->dest.offset = insn.displacement.value;
2294 ++
2295 ++ } else if (rex_w && !rex_b && modrm_rm == 4 && sib == 0x24) {
2296 ++
2297 ++ /* mov reg, disp(%rsp) */
2298 ++ *type = INSN_STACK;
2299 ++ op->src.type = OP_SRC_REG;
2300 ++ op->src.reg = op_to_cfi_reg[modrm_reg][rex_r];
2301 ++ op->dest.type = OP_DEST_REG_INDIRECT;
2302 ++ op->dest.reg = CFI_SP;
2303 ++ op->dest.offset = insn.displacement.value;
2304 ++ }
2305 ++
2306 ++ break;
2307 ++
2308 ++ case 0x8b:
2309 ++ if (rex_w && !rex_b && modrm_mod == 1 && modrm_rm == 5) {
2310 ++
2311 ++ /* mov disp(%rbp), reg */
2312 ++ *type = INSN_STACK;
2313 ++ op->src.type = OP_SRC_REG_INDIRECT;
2314 ++ op->src.reg = CFI_BP;
2315 ++ op->src.offset = insn.displacement.value;
2316 ++ op->dest.type = OP_DEST_REG;
2317 ++ op->dest.reg = op_to_cfi_reg[modrm_reg][rex_r];
2318 ++
2319 ++ } else if (rex_w && !rex_b && sib == 0x24 &&
2320 ++ modrm_mod != 3 && modrm_rm == 4) {
2321 ++
2322 ++ /* mov disp(%rsp), reg */
2323 ++ *type = INSN_STACK;
2324 ++ op->src.type = OP_SRC_REG_INDIRECT;
2325 ++ op->src.reg = CFI_SP;
2326 ++ op->src.offset = insn.displacement.value;
2327 ++ op->dest.type = OP_DEST_REG;
2328 ++ op->dest.reg = op_to_cfi_reg[modrm_reg][rex_r];
2329 ++ }
2330 ++
2331 + break;
2332 +
2333 + case 0x8d:
2334 +- if (insn.rex_prefix.nbytes &&
2335 +- insn.rex_prefix.bytes[0] == 0x48 &&
2336 +- insn.modrm.nbytes && insn.modrm.bytes[0] == 0x2c &&
2337 +- insn.sib.nbytes && insn.sib.bytes[0] == 0x24)
2338 +- /* lea %(rsp), %rbp */
2339 +- *type = INSN_FP_SETUP;
2340 ++ if (sib == 0x24 && rex_w && !rex_b && !rex_x) {
2341 ++
2342 ++ *type = INSN_STACK;
2343 ++ if (!insn.displacement.value) {
2344 ++ /* lea (%rsp), reg */
2345 ++ op->src.type = OP_SRC_REG;
2346 ++ } else {
2347 ++ /* lea disp(%rsp), reg */
2348 ++ op->src.type = OP_SRC_ADD;
2349 ++ op->src.offset = insn.displacement.value;
2350 ++ }
2351 ++ op->src.reg = CFI_SP;
2352 ++ op->dest.type = OP_DEST_REG;
2353 ++ op->dest.reg = op_to_cfi_reg[modrm_reg][rex_r];
2354 ++
2355 ++ } else if (rex == 0x48 && modrm == 0x65) {
2356 ++
2357 ++ /* lea disp(%rbp), %rsp */
2358 ++ *type = INSN_STACK;
2359 ++ op->src.type = OP_SRC_ADD;
2360 ++ op->src.reg = CFI_BP;
2361 ++ op->src.offset = insn.displacement.value;
2362 ++ op->dest.type = OP_DEST_REG;
2363 ++ op->dest.reg = CFI_SP;
2364 ++
2365 ++ } else if (rex == 0x49 && modrm == 0x62 &&
2366 ++ insn.displacement.value == -8) {
2367 ++
2368 ++ /*
2369 ++ * lea -0x8(%r10), %rsp
2370 ++ *
2371 ++ * Restoring rsp back to its original value after a
2372 ++ * stack realignment.
2373 ++ */
2374 ++ *type = INSN_STACK;
2375 ++ op->src.type = OP_SRC_ADD;
2376 ++ op->src.reg = CFI_R10;
2377 ++ op->src.offset = -8;
2378 ++ op->dest.type = OP_DEST_REG;
2379 ++ op->dest.reg = CFI_SP;
2380 ++
2381 ++ } else if (rex == 0x49 && modrm == 0x65 &&
2382 ++ insn.displacement.value == -16) {
2383 ++
2384 ++ /*
2385 ++ * lea -0x10(%r13), %rsp
2386 ++ *
2387 ++ * Restoring rsp back to its original value after a
2388 ++ * stack realignment.
2389 ++ */
2390 ++ *type = INSN_STACK;
2391 ++ op->src.type = OP_SRC_ADD;
2392 ++ op->src.reg = CFI_R13;
2393 ++ op->src.offset = -16;
2394 ++ op->dest.type = OP_DEST_REG;
2395 ++ op->dest.reg = CFI_SP;
2396 ++ }
2397 ++
2398 ++ break;
2399 ++
2400 ++ case 0x8f:
2401 ++ /* pop to mem */
2402 ++ *type = INSN_STACK;
2403 ++ op->src.type = OP_SRC_POP;
2404 ++ op->dest.type = OP_DEST_MEM;
2405 + break;
2406 +
2407 + case 0x90:
2408 + *type = INSN_NOP;
2409 + break;
2410 +
2411 ++ case 0x9c:
2412 ++ /* pushf */
2413 ++ *type = INSN_STACK;
2414 ++ op->src.type = OP_SRC_CONST;
2415 ++ op->dest.type = OP_DEST_PUSH;
2416 ++ break;
2417 ++
2418 ++ case 0x9d:
2419 ++ /* popf */
2420 ++ *type = INSN_STACK;
2421 ++ op->src.type = OP_SRC_POP;
2422 ++ op->dest.type = OP_DEST_MEM;
2423 ++ break;
2424 ++
2425 + case 0x0f:
2426 +- if (op2 >= 0x80 && op2 <= 0x8f)
2427 ++
2428 ++ if (op2 >= 0x80 && op2 <= 0x8f) {
2429 ++
2430 + *type = INSN_JUMP_CONDITIONAL;
2431 +- else if (op2 == 0x05 || op2 == 0x07 || op2 == 0x34 ||
2432 +- op2 == 0x35)
2433 ++
2434 ++ } else if (op2 == 0x05 || op2 == 0x07 || op2 == 0x34 ||
2435 ++ op2 == 0x35) {
2436 ++
2437 + /* sysenter, sysret */
2438 + *type = INSN_CONTEXT_SWITCH;
2439 +- else if (op2 == 0x0b || op2 == 0xb9)
2440 ++
2441 ++ } else if (op2 == 0x0b || op2 == 0xb9) {
2442 ++
2443 + /* ud2 */
2444 + *type = INSN_BUG;
2445 +- else if (op2 == 0x0d || op2 == 0x1f)
2446 ++
2447 ++ } else if (op2 == 0x0d || op2 == 0x1f) {
2448 ++
2449 + /* nopl/nopw */
2450 + *type = INSN_NOP;
2451 +- else if (op2 == 0x01 && insn.modrm.nbytes &&
2452 +- (insn.modrm.bytes[0] == 0xc2 ||
2453 +- insn.modrm.bytes[0] == 0xd8))
2454 +- /* vmlaunch, vmrun */
2455 +- *type = INSN_CONTEXT_SWITCH;
2456 ++
2457 ++ } else if (op2 == 0xa0 || op2 == 0xa8) {
2458 ++
2459 ++ /* push fs/gs */
2460 ++ *type = INSN_STACK;
2461 ++ op->src.type = OP_SRC_CONST;
2462 ++ op->dest.type = OP_DEST_PUSH;
2463 ++
2464 ++ } else if (op2 == 0xa1 || op2 == 0xa9) {
2465 ++
2466 ++ /* pop fs/gs */
2467 ++ *type = INSN_STACK;
2468 ++ op->src.type = OP_SRC_POP;
2469 ++ op->dest.type = OP_DEST_MEM;
2470 ++ }
2471 +
2472 + break;
2473 +
2474 +- case 0xc9: /* leave */
2475 +- *type = INSN_FP_RESTORE;
2476 ++ case 0xc9:
2477 ++ /*
2478 ++ * leave
2479 ++ *
2480 ++ * equivalent to:
2481 ++ * mov bp, sp
2482 ++ * pop bp
2483 ++ */
2484 ++ *type = INSN_STACK;
2485 ++ op->dest.type = OP_DEST_LEAVE;
2486 ++
2487 + break;
2488 +
2489 +- case 0xe3: /* jecxz/jrcxz */
2490 ++ case 0xe3:
2491 ++ /* jecxz/jrcxz */
2492 + *type = INSN_JUMP_CONDITIONAL;
2493 + break;
2494 +
2495 +@@ -161,14 +445,27 @@ int arch_decode_instruction(struct elf *elf, struct section *sec,
2496 + break;
2497 +
2498 + case 0xff:
2499 +- ext = X86_MODRM_REG(insn.modrm.bytes[0]);
2500 +- if (ext == 2 || ext == 3)
2501 ++ if (modrm_reg == 2 || modrm_reg == 3)
2502 ++
2503 + *type = INSN_CALL_DYNAMIC;
2504 +- else if (ext == 4)
2505 ++
2506 ++ else if (modrm_reg == 4)
2507 ++
2508 + *type = INSN_JUMP_DYNAMIC;
2509 +- else if (ext == 5) /*jmpf */
2510 ++
2511 ++ else if (modrm_reg == 5)
2512 ++
2513 ++ /* jmpf */
2514 + *type = INSN_CONTEXT_SWITCH;
2515 +
2516 ++ else if (modrm_reg == 6) {
2517 ++
2518 ++ /* push from mem */
2519 ++ *type = INSN_STACK;
2520 ++ op->src.type = OP_SRC_CONST;
2521 ++ op->dest.type = OP_DEST_PUSH;
2522 ++ }
2523 ++
2524 + break;
2525 +
2526 + default:
2527 +@@ -179,3 +476,21 @@ int arch_decode_instruction(struct elf *elf, struct section *sec,
2528 +
2529 + return 0;
2530 + }
2531 ++
2532 ++void arch_initial_func_cfi_state(struct cfi_state *state)
2533 ++{
2534 ++ int i;
2535 ++
2536 ++ for (i = 0; i < CFI_NUM_REGS; i++) {
2537 ++ state->regs[i].base = CFI_UNDEFINED;
2538 ++ state->regs[i].offset = 0;
2539 ++ }
2540 ++
2541 ++ /* initial CFA (call frame address) */
2542 ++ state->cfa.base = CFI_SP;
2543 ++ state->cfa.offset = 8;
2544 ++
2545 ++ /* initial RA (return address) */
2546 ++ state->regs[16].base = CFI_CFA;
2547 ++ state->regs[16].offset = -8;
2548 ++}
2549 +diff --git a/tools/objtool/arch/x86/include/asm/inat.h b/tools/objtool/arch/x86/include/asm/inat.h
2550 +new file mode 100644
2551 +index 000000000000..02aff0867211
2552 +--- /dev/null
2553 ++++ b/tools/objtool/arch/x86/include/asm/inat.h
2554 +@@ -0,0 +1,234 @@
2555 ++#ifndef _ASM_X86_INAT_H
2556 ++#define _ASM_X86_INAT_H
2557 ++/*
2558 ++ * x86 instruction attributes
2559 ++ *
2560 ++ * Written by Masami Hiramatsu <mhiramat@××××××.com>
2561 ++ *
2562 ++ * This program is free software; you can redistribute it and/or modify
2563 ++ * it under the terms of the GNU General Public License as published by
2564 ++ * the Free Software Foundation; either version 2 of the License, or
2565 ++ * (at your option) any later version.
2566 ++ *
2567 ++ * This program is distributed in the hope that it will be useful,
2568 ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2569 ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2570 ++ * GNU General Public License for more details.
2571 ++ *
2572 ++ * You should have received a copy of the GNU General Public License
2573 ++ * along with this program; if not, write to the Free Software
2574 ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
2575 ++ *
2576 ++ */
2577 ++#include <asm/inat_types.h>
2578 ++
2579 ++/*
2580 ++ * Internal bits. Don't use bitmasks directly, because these bits are
2581 ++ * unstable. You should use checking functions.
2582 ++ */
2583 ++
2584 ++#define INAT_OPCODE_TABLE_SIZE 256
2585 ++#define INAT_GROUP_TABLE_SIZE 8
2586 ++
2587 ++/* Legacy last prefixes */
2588 ++#define INAT_PFX_OPNDSZ 1 /* 0x66 */ /* LPFX1 */
2589 ++#define INAT_PFX_REPE 2 /* 0xF3 */ /* LPFX2 */
2590 ++#define INAT_PFX_REPNE 3 /* 0xF2 */ /* LPFX3 */
2591 ++/* Other Legacy prefixes */
2592 ++#define INAT_PFX_LOCK 4 /* 0xF0 */
2593 ++#define INAT_PFX_CS 5 /* 0x2E */
2594 ++#define INAT_PFX_DS 6 /* 0x3E */
2595 ++#define INAT_PFX_ES 7 /* 0x26 */
2596 ++#define INAT_PFX_FS 8 /* 0x64 */
2597 ++#define INAT_PFX_GS 9 /* 0x65 */
2598 ++#define INAT_PFX_SS 10 /* 0x36 */
2599 ++#define INAT_PFX_ADDRSZ 11 /* 0x67 */
2600 ++/* x86-64 REX prefix */
2601 ++#define INAT_PFX_REX 12 /* 0x4X */
2602 ++/* AVX VEX prefixes */
2603 ++#define INAT_PFX_VEX2 13 /* 2-bytes VEX prefix */
2604 ++#define INAT_PFX_VEX3 14 /* 3-bytes VEX prefix */
2605 ++#define INAT_PFX_EVEX 15 /* EVEX prefix */
2606 ++
2607 ++#define INAT_LSTPFX_MAX 3
2608 ++#define INAT_LGCPFX_MAX 11
2609 ++
2610 ++/* Immediate size */
2611 ++#define INAT_IMM_BYTE 1
2612 ++#define INAT_IMM_WORD 2
2613 ++#define INAT_IMM_DWORD 3
2614 ++#define INAT_IMM_QWORD 4
2615 ++#define INAT_IMM_PTR 5
2616 ++#define INAT_IMM_VWORD32 6
2617 ++#define INAT_IMM_VWORD 7
2618 ++
2619 ++/* Legacy prefix */
2620 ++#define INAT_PFX_OFFS 0
2621 ++#define INAT_PFX_BITS 4
2622 ++#define INAT_PFX_MAX ((1 << INAT_PFX_BITS) - 1)
2623 ++#define INAT_PFX_MASK (INAT_PFX_MAX << INAT_PFX_OFFS)
2624 ++/* Escape opcodes */
2625 ++#define INAT_ESC_OFFS (INAT_PFX_OFFS + INAT_PFX_BITS)
2626 ++#define INAT_ESC_BITS 2
2627 ++#define INAT_ESC_MAX ((1 << INAT_ESC_BITS) - 1)
2628 ++#define INAT_ESC_MASK (INAT_ESC_MAX << INAT_ESC_OFFS)
2629 ++/* Group opcodes (1-16) */
2630 ++#define INAT_GRP_OFFS (INAT_ESC_OFFS + INAT_ESC_BITS)
2631 ++#define INAT_GRP_BITS 5
2632 ++#define INAT_GRP_MAX ((1 << INAT_GRP_BITS) - 1)
2633 ++#define INAT_GRP_MASK (INAT_GRP_MAX << INAT_GRP_OFFS)
2634 ++/* Immediates */
2635 ++#define INAT_IMM_OFFS (INAT_GRP_OFFS + INAT_GRP_BITS)
2636 ++#define INAT_IMM_BITS 3
2637 ++#define INAT_IMM_MASK (((1 << INAT_IMM_BITS) - 1) << INAT_IMM_OFFS)
2638 ++/* Flags */
2639 ++#define INAT_FLAG_OFFS (INAT_IMM_OFFS + INAT_IMM_BITS)
2640 ++#define INAT_MODRM (1 << (INAT_FLAG_OFFS))
2641 ++#define INAT_FORCE64 (1 << (INAT_FLAG_OFFS + 1))
2642 ++#define INAT_SCNDIMM (1 << (INAT_FLAG_OFFS + 2))
2643 ++#define INAT_MOFFSET (1 << (INAT_FLAG_OFFS + 3))
2644 ++#define INAT_VARIANT (1 << (INAT_FLAG_OFFS + 4))
2645 ++#define INAT_VEXOK (1 << (INAT_FLAG_OFFS + 5))
2646 ++#define INAT_VEXONLY (1 << (INAT_FLAG_OFFS + 6))
2647 ++#define INAT_EVEXONLY (1 << (INAT_FLAG_OFFS + 7))
2648 ++/* Attribute making macros for attribute tables */
2649 ++#define INAT_MAKE_PREFIX(pfx) (pfx << INAT_PFX_OFFS)
2650 ++#define INAT_MAKE_ESCAPE(esc) (esc << INAT_ESC_OFFS)
2651 ++#define INAT_MAKE_GROUP(grp) ((grp << INAT_GRP_OFFS) | INAT_MODRM)
2652 ++#define INAT_MAKE_IMM(imm) (imm << INAT_IMM_OFFS)
2653 ++
2654 ++/* Attribute search APIs */
2655 ++extern insn_attr_t inat_get_opcode_attribute(insn_byte_t opcode);
2656 ++extern int inat_get_last_prefix_id(insn_byte_t last_pfx);
2657 ++extern insn_attr_t inat_get_escape_attribute(insn_byte_t opcode,
2658 ++ int lpfx_id,
2659 ++ insn_attr_t esc_attr);
2660 ++extern insn_attr_t inat_get_group_attribute(insn_byte_t modrm,
2661 ++ int lpfx_id,
2662 ++ insn_attr_t esc_attr);
2663 ++extern insn_attr_t inat_get_avx_attribute(insn_byte_t opcode,
2664 ++ insn_byte_t vex_m,
2665 ++ insn_byte_t vex_pp);
2666 ++
2667 ++/* Attribute checking functions */
2668 ++static inline int inat_is_legacy_prefix(insn_attr_t attr)
2669 ++{
2670 ++ attr &= INAT_PFX_MASK;
2671 ++ return attr && attr <= INAT_LGCPFX_MAX;
2672 ++}
2673 ++
2674 ++static inline int inat_is_address_size_prefix(insn_attr_t attr)
2675 ++{
2676 ++ return (attr & INAT_PFX_MASK) == INAT_PFX_ADDRSZ;
2677 ++}
2678 ++
2679 ++static inline int inat_is_operand_size_prefix(insn_attr_t attr)
2680 ++{
2681 ++ return (attr & INAT_PFX_MASK) == INAT_PFX_OPNDSZ;
2682 ++}
2683 ++
2684 ++static inline int inat_is_rex_prefix(insn_attr_t attr)
2685 ++{
2686 ++ return (attr & INAT_PFX_MASK) == INAT_PFX_REX;
2687 ++}
2688 ++
2689 ++static inline int inat_last_prefix_id(insn_attr_t attr)
2690 ++{
2691 ++ if ((attr & INAT_PFX_MASK) > INAT_LSTPFX_MAX)
2692 ++ return 0;
2693 ++ else
2694 ++ return attr & INAT_PFX_MASK;
2695 ++}
2696 ++
2697 ++static inline int inat_is_vex_prefix(insn_attr_t attr)
2698 ++{
2699 ++ attr &= INAT_PFX_MASK;
2700 ++ return attr == INAT_PFX_VEX2 || attr == INAT_PFX_VEX3 ||
2701 ++ attr == INAT_PFX_EVEX;
2702 ++}
2703 ++
2704 ++static inline int inat_is_evex_prefix(insn_attr_t attr)
2705 ++{
2706 ++ return (attr & INAT_PFX_MASK) == INAT_PFX_EVEX;
2707 ++}
2708 ++
2709 ++static inline int inat_is_vex3_prefix(insn_attr_t attr)
2710 ++{
2711 ++ return (attr & INAT_PFX_MASK) == INAT_PFX_VEX3;
2712 ++}
2713 ++
2714 ++static inline int inat_is_escape(insn_attr_t attr)
2715 ++{
2716 ++ return attr & INAT_ESC_MASK;
2717 ++}
2718 ++
2719 ++static inline int inat_escape_id(insn_attr_t attr)
2720 ++{
2721 ++ return (attr & INAT_ESC_MASK) >> INAT_ESC_OFFS;
2722 ++}
2723 ++
2724 ++static inline int inat_is_group(insn_attr_t attr)
2725 ++{
2726 ++ return attr & INAT_GRP_MASK;
2727 ++}
2728 ++
2729 ++static inline int inat_group_id(insn_attr_t attr)
2730 ++{
2731 ++ return (attr & INAT_GRP_MASK) >> INAT_GRP_OFFS;
2732 ++}
2733 ++
2734 ++static inline int inat_group_common_attribute(insn_attr_t attr)
2735 ++{
2736 ++ return attr & ~INAT_GRP_MASK;
2737 ++}
2738 ++
2739 ++static inline int inat_has_immediate(insn_attr_t attr)
2740 ++{
2741 ++ return attr & INAT_IMM_MASK;
2742 ++}
2743 ++
2744 ++static inline int inat_immediate_size(insn_attr_t attr)
2745 ++{
2746 ++ return (attr & INAT_IMM_MASK) >> INAT_IMM_OFFS;
2747 ++}
2748 ++
2749 ++static inline int inat_has_modrm(insn_attr_t attr)
2750 ++{
2751 ++ return attr & INAT_MODRM;
2752 ++}
2753 ++
2754 ++static inline int inat_is_force64(insn_attr_t attr)
2755 ++{
2756 ++ return attr & INAT_FORCE64;
2757 ++}
2758 ++
2759 ++static inline int inat_has_second_immediate(insn_attr_t attr)
2760 ++{
2761 ++ return attr & INAT_SCNDIMM;
2762 ++}
2763 ++
2764 ++static inline int inat_has_moffset(insn_attr_t attr)
2765 ++{
2766 ++ return attr & INAT_MOFFSET;
2767 ++}
2768 ++
2769 ++static inline int inat_has_variant(insn_attr_t attr)
2770 ++{
2771 ++ return attr & INAT_VARIANT;
2772 ++}
2773 ++
2774 ++static inline int inat_accept_vex(insn_attr_t attr)
2775 ++{
2776 ++ return attr & INAT_VEXOK;
2777 ++}
2778 ++
2779 ++static inline int inat_must_vex(insn_attr_t attr)
2780 ++{
2781 ++ return attr & (INAT_VEXONLY | INAT_EVEXONLY);
2782 ++}
2783 ++
2784 ++static inline int inat_must_evex(insn_attr_t attr)
2785 ++{
2786 ++ return attr & INAT_EVEXONLY;
2787 ++}
2788 ++#endif
2789 +diff --git a/tools/objtool/arch/x86/include/asm/inat_types.h b/tools/objtool/arch/x86/include/asm/inat_types.h
2790 +new file mode 100644
2791 +index 000000000000..cb3c20ce39cf
2792 +--- /dev/null
2793 ++++ b/tools/objtool/arch/x86/include/asm/inat_types.h
2794 +@@ -0,0 +1,29 @@
2795 ++#ifndef _ASM_X86_INAT_TYPES_H
2796 ++#define _ASM_X86_INAT_TYPES_H
2797 ++/*
2798 ++ * x86 instruction attributes
2799 ++ *
2800 ++ * Written by Masami Hiramatsu <mhiramat@××××××.com>
2801 ++ *
2802 ++ * This program is free software; you can redistribute it and/or modify
2803 ++ * it under the terms of the GNU General Public License as published by
2804 ++ * the Free Software Foundation; either version 2 of the License, or
2805 ++ * (at your option) any later version.
2806 ++ *
2807 ++ * This program is distributed in the hope that it will be useful,
2808 ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2809 ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2810 ++ * GNU General Public License for more details.
2811 ++ *
2812 ++ * You should have received a copy of the GNU General Public License
2813 ++ * along with this program; if not, write to the Free Software
2814 ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
2815 ++ *
2816 ++ */
2817 ++
2818 ++/* Instruction attributes */
2819 ++typedef unsigned int insn_attr_t;
2820 ++typedef unsigned char insn_byte_t;
2821 ++typedef signed int insn_value_t;
2822 ++
2823 ++#endif
2824 +diff --git a/tools/objtool/arch/x86/include/asm/insn.h b/tools/objtool/arch/x86/include/asm/insn.h
2825 +new file mode 100644
2826 +index 000000000000..b3e32b010ab1
2827 +--- /dev/null
2828 ++++ b/tools/objtool/arch/x86/include/asm/insn.h
2829 +@@ -0,0 +1,211 @@
2830 ++#ifndef _ASM_X86_INSN_H
2831 ++#define _ASM_X86_INSN_H
2832 ++/*
2833 ++ * x86 instruction analysis
2834 ++ *
2835 ++ * This program is free software; you can redistribute it and/or modify
2836 ++ * it under the terms of the GNU General Public License as published by
2837 ++ * the Free Software Foundation; either version 2 of the License, or
2838 ++ * (at your option) any later version.
2839 ++ *
2840 ++ * This program is distributed in the hope that it will be useful,
2841 ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2842 ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2843 ++ * GNU General Public License for more details.
2844 ++ *
2845 ++ * You should have received a copy of the GNU General Public License
2846 ++ * along with this program; if not, write to the Free Software
2847 ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
2848 ++ *
2849 ++ * Copyright (C) IBM Corporation, 2009
2850 ++ */
2851 ++
2852 ++/* insn_attr_t is defined in inat.h */
2853 ++#include <asm/inat.h>
2854 ++
2855 ++struct insn_field {
2856 ++ union {
2857 ++ insn_value_t value;
2858 ++ insn_byte_t bytes[4];
2859 ++ };
2860 ++ /* !0 if we've run insn_get_xxx() for this field */
2861 ++ unsigned char got;
2862 ++ unsigned char nbytes;
2863 ++};
2864 ++
2865 ++struct insn {
2866 ++ struct insn_field prefixes; /*
2867 ++ * Prefixes
2868 ++ * prefixes.bytes[3]: last prefix
2869 ++ */
2870 ++ struct insn_field rex_prefix; /* REX prefix */
2871 ++ struct insn_field vex_prefix; /* VEX prefix */
2872 ++ struct insn_field opcode; /*
2873 ++ * opcode.bytes[0]: opcode1
2874 ++ * opcode.bytes[1]: opcode2
2875 ++ * opcode.bytes[2]: opcode3
2876 ++ */
2877 ++ struct insn_field modrm;
2878 ++ struct insn_field sib;
2879 ++ struct insn_field displacement;
2880 ++ union {
2881 ++ struct insn_field immediate;
2882 ++ struct insn_field moffset1; /* for 64bit MOV */
2883 ++ struct insn_field immediate1; /* for 64bit imm or off16/32 */
2884 ++ };
2885 ++ union {
2886 ++ struct insn_field moffset2; /* for 64bit MOV */
2887 ++ struct insn_field immediate2; /* for 64bit imm or seg16 */
2888 ++ };
2889 ++
2890 ++ insn_attr_t attr;
2891 ++ unsigned char opnd_bytes;
2892 ++ unsigned char addr_bytes;
2893 ++ unsigned char length;
2894 ++ unsigned char x86_64;
2895 ++
2896 ++ const insn_byte_t *kaddr; /* kernel address of insn to analyze */
2897 ++ const insn_byte_t *end_kaddr; /* kernel address of last insn in buffer */
2898 ++ const insn_byte_t *next_byte;
2899 ++};
2900 ++
2901 ++#define MAX_INSN_SIZE 15
2902 ++
2903 ++#define X86_MODRM_MOD(modrm) (((modrm) & 0xc0) >> 6)
2904 ++#define X86_MODRM_REG(modrm) (((modrm) & 0x38) >> 3)
2905 ++#define X86_MODRM_RM(modrm) ((modrm) & 0x07)
2906 ++
2907 ++#define X86_SIB_SCALE(sib) (((sib) & 0xc0) >> 6)
2908 ++#define X86_SIB_INDEX(sib) (((sib) & 0x38) >> 3)
2909 ++#define X86_SIB_BASE(sib) ((sib) & 0x07)
2910 ++
2911 ++#define X86_REX_W(rex) ((rex) & 8)
2912 ++#define X86_REX_R(rex) ((rex) & 4)
2913 ++#define X86_REX_X(rex) ((rex) & 2)
2914 ++#define X86_REX_B(rex) ((rex) & 1)
2915 ++
2916 ++/* VEX bit flags */
2917 ++#define X86_VEX_W(vex) ((vex) & 0x80) /* VEX3 Byte2 */
2918 ++#define X86_VEX_R(vex) ((vex) & 0x80) /* VEX2/3 Byte1 */
2919 ++#define X86_VEX_X(vex) ((vex) & 0x40) /* VEX3 Byte1 */
2920 ++#define X86_VEX_B(vex) ((vex) & 0x20) /* VEX3 Byte1 */
2921 ++#define X86_VEX_L(vex) ((vex) & 0x04) /* VEX3 Byte2, VEX2 Byte1 */
2922 ++/* VEX bit fields */
2923 ++#define X86_EVEX_M(vex) ((vex) & 0x03) /* EVEX Byte1 */
2924 ++#define X86_VEX3_M(vex) ((vex) & 0x1f) /* VEX3 Byte1 */
2925 ++#define X86_VEX2_M 1 /* VEX2.M always 1 */
2926 ++#define X86_VEX_V(vex) (((vex) & 0x78) >> 3) /* VEX3 Byte2, VEX2 Byte1 */
2927 ++#define X86_VEX_P(vex) ((vex) & 0x03) /* VEX3 Byte2, VEX2 Byte1 */
2928 ++#define X86_VEX_M_MAX 0x1f /* VEX3.M Maximum value */
2929 ++
2930 ++extern void insn_init(struct insn *insn, const void *kaddr, int buf_len, int x86_64);
2931 ++extern void insn_get_prefixes(struct insn *insn);
2932 ++extern void insn_get_opcode(struct insn *insn);
2933 ++extern void insn_get_modrm(struct insn *insn);
2934 ++extern void insn_get_sib(struct insn *insn);
2935 ++extern void insn_get_displacement(struct insn *insn);
2936 ++extern void insn_get_immediate(struct insn *insn);
2937 ++extern void insn_get_length(struct insn *insn);
2938 ++
2939 ++/* Attribute will be determined after getting ModRM (for opcode groups) */
2940 ++static inline void insn_get_attribute(struct insn *insn)
2941 ++{
2942 ++ insn_get_modrm(insn);
2943 ++}
2944 ++
2945 ++/* Instruction uses RIP-relative addressing */
2946 ++extern int insn_rip_relative(struct insn *insn);
2947 ++
2948 ++/* Init insn for kernel text */
2949 ++static inline void kernel_insn_init(struct insn *insn,
2950 ++ const void *kaddr, int buf_len)
2951 ++{
2952 ++#ifdef CONFIG_X86_64
2953 ++ insn_init(insn, kaddr, buf_len, 1);
2954 ++#else /* CONFIG_X86_32 */
2955 ++ insn_init(insn, kaddr, buf_len, 0);
2956 ++#endif
2957 ++}
2958 ++
2959 ++static inline int insn_is_avx(struct insn *insn)
2960 ++{
2961 ++ if (!insn->prefixes.got)
2962 ++ insn_get_prefixes(insn);
2963 ++ return (insn->vex_prefix.value != 0);
2964 ++}
2965 ++
2966 ++static inline int insn_is_evex(struct insn *insn)
2967 ++{
2968 ++ if (!insn->prefixes.got)
2969 ++ insn_get_prefixes(insn);
2970 ++ return (insn->vex_prefix.nbytes == 4);
2971 ++}
2972 ++
2973 ++/* Ensure this instruction is decoded completely */
2974 ++static inline int insn_complete(struct insn *insn)
2975 ++{
2976 ++ return insn->opcode.got && insn->modrm.got && insn->sib.got &&
2977 ++ insn->displacement.got && insn->immediate.got;
2978 ++}
2979 ++
2980 ++static inline insn_byte_t insn_vex_m_bits(struct insn *insn)
2981 ++{
2982 ++ if (insn->vex_prefix.nbytes == 2) /* 2 bytes VEX */
2983 ++ return X86_VEX2_M;
2984 ++ else if (insn->vex_prefix.nbytes == 3) /* 3 bytes VEX */
2985 ++ return X86_VEX3_M(insn->vex_prefix.bytes[1]);
2986 ++ else /* EVEX */
2987 ++ return X86_EVEX_M(insn->vex_prefix.bytes[1]);
2988 ++}
2989 ++
2990 ++static inline insn_byte_t insn_vex_p_bits(struct insn *insn)
2991 ++{
2992 ++ if (insn->vex_prefix.nbytes == 2) /* 2 bytes VEX */
2993 ++ return X86_VEX_P(insn->vex_prefix.bytes[1]);
2994 ++ else
2995 ++ return X86_VEX_P(insn->vex_prefix.bytes[2]);
2996 ++}
2997 ++
2998 ++/* Get the last prefix id from last prefix or VEX prefix */
2999 ++static inline int insn_last_prefix_id(struct insn *insn)
3000 ++{
3001 ++ if (insn_is_avx(insn))
3002 ++ return insn_vex_p_bits(insn); /* VEX_p is a SIMD prefix id */
3003 ++
3004 ++ if (insn->prefixes.bytes[3])
3005 ++ return inat_get_last_prefix_id(insn->prefixes.bytes[3]);
3006 ++
3007 ++ return 0;
3008 ++}
3009 ++
3010 ++/* Offset of each field from kaddr */
3011 ++static inline int insn_offset_rex_prefix(struct insn *insn)
3012 ++{
3013 ++ return insn->prefixes.nbytes;
3014 ++}
3015 ++static inline int insn_offset_vex_prefix(struct insn *insn)
3016 ++{
3017 ++ return insn_offset_rex_prefix(insn) + insn->rex_prefix.nbytes;
3018 ++}
3019 ++static inline int insn_offset_opcode(struct insn *insn)
3020 ++{
3021 ++ return insn_offset_vex_prefix(insn) + insn->vex_prefix.nbytes;
3022 ++}
3023 ++static inline int insn_offset_modrm(struct insn *insn)
3024 ++{
3025 ++ return insn_offset_opcode(insn) + insn->opcode.nbytes;
3026 ++}
3027 ++static inline int insn_offset_sib(struct insn *insn)
3028 ++{
3029 ++ return insn_offset_modrm(insn) + insn->modrm.nbytes;
3030 ++}
3031 ++static inline int insn_offset_displacement(struct insn *insn)
3032 ++{
3033 ++ return insn_offset_sib(insn) + insn->sib.nbytes;
3034 ++}
3035 ++static inline int insn_offset_immediate(struct insn *insn)
3036 ++{
3037 ++ return insn_offset_displacement(insn) + insn->displacement.nbytes;
3038 ++}
3039 ++
3040 ++#endif /* _ASM_X86_INSN_H */
3041 +diff --git a/tools/objtool/arch/x86/include/asm/orc_types.h b/tools/objtool/arch/x86/include/asm/orc_types.h
3042 +new file mode 100644
3043 +index 000000000000..7dc777a6cb40
3044 +--- /dev/null
3045 ++++ b/tools/objtool/arch/x86/include/asm/orc_types.h
3046 +@@ -0,0 +1,107 @@
3047 ++/*
3048 ++ * Copyright (C) 2017 Josh Poimboeuf <jpoimboe@××××××.com>
3049 ++ *
3050 ++ * This program is free software; you can redistribute it and/or
3051 ++ * modify it under the terms of the GNU General Public License
3052 ++ * as published by the Free Software Foundation; either version 2
3053 ++ * of the License, or (at your option) any later version.
3054 ++ *
3055 ++ * This program is distributed in the hope that it will be useful,
3056 ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3057 ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3058 ++ * GNU General Public License for more details.
3059 ++ *
3060 ++ * You should have received a copy of the GNU General Public License
3061 ++ * along with this program; if not, see <http://www.gnu.org/licenses/>.
3062 ++ */
3063 ++
3064 ++#ifndef _ORC_TYPES_H
3065 ++#define _ORC_TYPES_H
3066 ++
3067 ++#include <linux/types.h>
3068 ++#include <linux/compiler.h>
3069 ++
3070 ++/*
3071 ++ * The ORC_REG_* registers are base registers which are used to find other
3072 ++ * registers on the stack.
3073 ++ *
3074 ++ * ORC_REG_PREV_SP, also known as DWARF Call Frame Address (CFA), is the
3075 ++ * address of the previous frame: the caller's SP before it called the current
3076 ++ * function.
3077 ++ *
3078 ++ * ORC_REG_UNDEFINED means the corresponding register's value didn't change in
3079 ++ * the current frame.
3080 ++ *
3081 ++ * The most commonly used base registers are SP and BP -- which the previous SP
3082 ++ * is usually based on -- and PREV_SP and UNDEFINED -- which the previous BP is
3083 ++ * usually based on.
3084 ++ *
3085 ++ * The rest of the base registers are needed for special cases like entry code
3086 ++ * and GCC realigned stacks.
3087 ++ */
3088 ++#define ORC_REG_UNDEFINED 0
3089 ++#define ORC_REG_PREV_SP 1
3090 ++#define ORC_REG_DX 2
3091 ++#define ORC_REG_DI 3
3092 ++#define ORC_REG_BP 4
3093 ++#define ORC_REG_SP 5
3094 ++#define ORC_REG_R10 6
3095 ++#define ORC_REG_R13 7
3096 ++#define ORC_REG_BP_INDIRECT 8
3097 ++#define ORC_REG_SP_INDIRECT 9
3098 ++#define ORC_REG_MAX 15
3099 ++
3100 ++/*
3101 ++ * ORC_TYPE_CALL: Indicates that sp_reg+sp_offset resolves to PREV_SP (the
3102 ++ * caller's SP right before it made the call). Used for all callable
3103 ++ * functions, i.e. all C code and all callable asm functions.
3104 ++ *
3105 ++ * ORC_TYPE_REGS: Used in entry code to indicate that sp_reg+sp_offset points
3106 ++ * to a fully populated pt_regs from a syscall, interrupt, or exception.
3107 ++ *
3108 ++ * ORC_TYPE_REGS_IRET: Used in entry code to indicate that sp_reg+sp_offset
3109 ++ * points to the iret return frame.
3110 ++ *
3111 ++ * The UNWIND_HINT macros are used only for the unwind_hint struct. They
3112 ++ * aren't used in struct orc_entry due to size and complexity constraints.
3113 ++ * Objtool converts them to real types when it converts the hints to orc
3114 ++ * entries.
3115 ++ */
3116 ++#define ORC_TYPE_CALL 0
3117 ++#define ORC_TYPE_REGS 1
3118 ++#define ORC_TYPE_REGS_IRET 2
3119 ++#define UNWIND_HINT_TYPE_SAVE 3
3120 ++#define UNWIND_HINT_TYPE_RESTORE 4
3121 ++
3122 ++#ifndef __ASSEMBLY__
3123 ++/*
3124 ++ * This struct is more or less a vastly simplified version of the DWARF Call
3125 ++ * Frame Information standard. It contains only the necessary parts of DWARF
3126 ++ * CFI, simplified for ease of access by the in-kernel unwinder. It tells the
3127 ++ * unwinder how to find the previous SP and BP (and sometimes entry regs) on
3128 ++ * the stack for a given code address. Each instance of the struct corresponds
3129 ++ * to one or more code locations.
3130 ++ */
3131 ++struct orc_entry {
3132 ++ s16 sp_offset;
3133 ++ s16 bp_offset;
3134 ++ unsigned sp_reg:4;
3135 ++ unsigned bp_reg:4;
3136 ++ unsigned type:2;
3137 ++};
3138 ++
3139 ++/*
3140 ++ * This struct is used by asm and inline asm code to manually annotate the
3141 ++ * location of registers on the stack for the ORC unwinder.
3142 ++ *
3143 ++ * Type can be either ORC_TYPE_* or UNWIND_HINT_TYPE_*.
3144 ++ */
3145 ++struct unwind_hint {
3146 ++ u32 ip;
3147 ++ s16 sp_offset;
3148 ++ u8 sp_reg;
3149 ++ u8 type;
3150 ++};
3151 ++#endif /* __ASSEMBLY__ */
3152 ++
3153 ++#endif /* _ORC_TYPES_H */
3154 +diff --git a/tools/objtool/arch/x86/insn/gen-insn-attr-x86.awk b/tools/objtool/arch/x86/insn/gen-insn-attr-x86.awk
3155 +deleted file mode 100644
3156 +index a3d2c62fd805..000000000000
3157 +--- a/tools/objtool/arch/x86/insn/gen-insn-attr-x86.awk
3158 ++++ /dev/null
3159 +@@ -1,392 +0,0 @@
3160 +-#!/bin/awk -f
3161 +-# gen-insn-attr-x86.awk: Instruction attribute table generator
3162 +-# Written by Masami Hiramatsu <mhiramat@××××××.com>
3163 +-#
3164 +-# Usage: awk -f gen-insn-attr-x86.awk x86-opcode-map.txt > inat-tables.c
3165 +-
3166 +-# Awk implementation sanity check
3167 +-function check_awk_implement() {
3168 +- if (sprintf("%x", 0) != "0")
3169 +- return "Your awk has a printf-format problem."
3170 +- return ""
3171 +-}
3172 +-
3173 +-# Clear working vars
3174 +-function clear_vars() {
3175 +- delete table
3176 +- delete lptable2
3177 +- delete lptable1
3178 +- delete lptable3
3179 +- eid = -1 # escape id
3180 +- gid = -1 # group id
3181 +- aid = -1 # AVX id
3182 +- tname = ""
3183 +-}
3184 +-
3185 +-BEGIN {
3186 +- # Implementation error checking
3187 +- awkchecked = check_awk_implement()
3188 +- if (awkchecked != "") {
3189 +- print "Error: " awkchecked > "/dev/stderr"
3190 +- print "Please try to use gawk." > "/dev/stderr"
3191 +- exit 1
3192 +- }
3193 +-
3194 +- # Setup generating tables
3195 +- print "/* x86 opcode map generated from x86-opcode-map.txt */"
3196 +- print "/* Do not change this code. */\n"
3197 +- ggid = 1
3198 +- geid = 1
3199 +- gaid = 0
3200 +- delete etable
3201 +- delete gtable
3202 +- delete atable
3203 +-
3204 +- opnd_expr = "^[A-Za-z/]"
3205 +- ext_expr = "^\\("
3206 +- sep_expr = "^\\|$"
3207 +- group_expr = "^Grp[0-9A-Za-z]+"
3208 +-
3209 +- imm_expr = "^[IJAOL][a-z]"
3210 +- imm_flag["Ib"] = "INAT_MAKE_IMM(INAT_IMM_BYTE)"
3211 +- imm_flag["Jb"] = "INAT_MAKE_IMM(INAT_IMM_BYTE)"
3212 +- imm_flag["Iw"] = "INAT_MAKE_IMM(INAT_IMM_WORD)"
3213 +- imm_flag["Id"] = "INAT_MAKE_IMM(INAT_IMM_DWORD)"
3214 +- imm_flag["Iq"] = "INAT_MAKE_IMM(INAT_IMM_QWORD)"
3215 +- imm_flag["Ap"] = "INAT_MAKE_IMM(INAT_IMM_PTR)"
3216 +- imm_flag["Iz"] = "INAT_MAKE_IMM(INAT_IMM_VWORD32)"
3217 +- imm_flag["Jz"] = "INAT_MAKE_IMM(INAT_IMM_VWORD32)"
3218 +- imm_flag["Iv"] = "INAT_MAKE_IMM(INAT_IMM_VWORD)"
3219 +- imm_flag["Ob"] = "INAT_MOFFSET"
3220 +- imm_flag["Ov"] = "INAT_MOFFSET"
3221 +- imm_flag["Lx"] = "INAT_MAKE_IMM(INAT_IMM_BYTE)"
3222 +-
3223 +- modrm_expr = "^([CDEGMNPQRSUVW/][a-z]+|NTA|T[012])"
3224 +- force64_expr = "\\([df]64\\)"
3225 +- rex_expr = "^REX(\\.[XRWB]+)*"
3226 +- fpu_expr = "^ESC" # TODO
3227 +-
3228 +- lprefix1_expr = "\\((66|!F3)\\)"
3229 +- lprefix2_expr = "\\(F3\\)"
3230 +- lprefix3_expr = "\\((F2|!F3|66\\&F2)\\)"
3231 +- lprefix_expr = "\\((66|F2|F3)\\)"
3232 +- max_lprefix = 4
3233 +-
3234 +- # All opcodes starting with lower-case 'v', 'k' or with (v1) superscript
3235 +- # accepts VEX prefix
3236 +- vexok_opcode_expr = "^[vk].*"
3237 +- vexok_expr = "\\(v1\\)"
3238 +- # All opcodes with (v) superscript supports *only* VEX prefix
3239 +- vexonly_expr = "\\(v\\)"
3240 +- # All opcodes with (ev) superscript supports *only* EVEX prefix
3241 +- evexonly_expr = "\\(ev\\)"
3242 +-
3243 +- prefix_expr = "\\(Prefix\\)"
3244 +- prefix_num["Operand-Size"] = "INAT_PFX_OPNDSZ"
3245 +- prefix_num["REPNE"] = "INAT_PFX_REPNE"
3246 +- prefix_num["REP/REPE"] = "INAT_PFX_REPE"
3247 +- prefix_num["XACQUIRE"] = "INAT_PFX_REPNE"
3248 +- prefix_num["XRELEASE"] = "INAT_PFX_REPE"
3249 +- prefix_num["LOCK"] = "INAT_PFX_LOCK"
3250 +- prefix_num["SEG=CS"] = "INAT_PFX_CS"
3251 +- prefix_num["SEG=DS"] = "INAT_PFX_DS"
3252 +- prefix_num["SEG=ES"] = "INAT_PFX_ES"
3253 +- prefix_num["SEG=FS"] = "INAT_PFX_FS"
3254 +- prefix_num["SEG=GS"] = "INAT_PFX_GS"
3255 +- prefix_num["SEG=SS"] = "INAT_PFX_SS"
3256 +- prefix_num["Address-Size"] = "INAT_PFX_ADDRSZ"
3257 +- prefix_num["VEX+1byte"] = "INAT_PFX_VEX2"
3258 +- prefix_num["VEX+2byte"] = "INAT_PFX_VEX3"
3259 +- prefix_num["EVEX"] = "INAT_PFX_EVEX"
3260 +-
3261 +- clear_vars()
3262 +-}
3263 +-
3264 +-function semantic_error(msg) {
3265 +- print "Semantic error at " NR ": " msg > "/dev/stderr"
3266 +- exit 1
3267 +-}
3268 +-
3269 +-function debug(msg) {
3270 +- print "DEBUG: " msg
3271 +-}
3272 +-
3273 +-function array_size(arr, i,c) {
3274 +- c = 0
3275 +- for (i in arr)
3276 +- c++
3277 +- return c
3278 +-}
3279 +-
3280 +-/^Table:/ {
3281 +- print "/* " $0 " */"
3282 +- if (tname != "")
3283 +- semantic_error("Hit Table: before EndTable:.");
3284 +-}
3285 +-
3286 +-/^Referrer:/ {
3287 +- if (NF != 1) {
3288 +- # escape opcode table
3289 +- ref = ""
3290 +- for (i = 2; i <= NF; i++)
3291 +- ref = ref $i
3292 +- eid = escape[ref]
3293 +- tname = sprintf("inat_escape_table_%d", eid)
3294 +- }
3295 +-}
3296 +-
3297 +-/^AVXcode:/ {
3298 +- if (NF != 1) {
3299 +- # AVX/escape opcode table
3300 +- aid = $2
3301 +- if (gaid <= aid)
3302 +- gaid = aid + 1
3303 +- if (tname == "") # AVX only opcode table
3304 +- tname = sprintf("inat_avx_table_%d", $2)
3305 +- }
3306 +- if (aid == -1 && eid == -1) # primary opcode table
3307 +- tname = "inat_primary_table"
3308 +-}
3309 +-
3310 +-/^GrpTable:/ {
3311 +- print "/* " $0 " */"
3312 +- if (!($2 in group))
3313 +- semantic_error("No group: " $2 )
3314 +- gid = group[$2]
3315 +- tname = "inat_group_table_" gid
3316 +-}
3317 +-
3318 +-function print_table(tbl,name,fmt,n)
3319 +-{
3320 +- print "const insn_attr_t " name " = {"
3321 +- for (i = 0; i < n; i++) {
3322 +- id = sprintf(fmt, i)
3323 +- if (tbl[id])
3324 +- print " [" id "] = " tbl[id] ","
3325 +- }
3326 +- print "};"
3327 +-}
3328 +-
3329 +-/^EndTable/ {
3330 +- if (gid != -1) {
3331 +- # print group tables
3332 +- if (array_size(table) != 0) {
3333 +- print_table(table, tname "[INAT_GROUP_TABLE_SIZE]",
3334 +- "0x%x", 8)
3335 +- gtable[gid,0] = tname
3336 +- }
3337 +- if (array_size(lptable1) != 0) {
3338 +- print_table(lptable1, tname "_1[INAT_GROUP_TABLE_SIZE]",
3339 +- "0x%x", 8)
3340 +- gtable[gid,1] = tname "_1"
3341 +- }
3342 +- if (array_size(lptable2) != 0) {
3343 +- print_table(lptable2, tname "_2[INAT_GROUP_TABLE_SIZE]",
3344 +- "0x%x", 8)
3345 +- gtable[gid,2] = tname "_2"
3346 +- }
3347 +- if (array_size(lptable3) != 0) {
3348 +- print_table(lptable3, tname "_3[INAT_GROUP_TABLE_SIZE]",
3349 +- "0x%x", 8)
3350 +- gtable[gid,3] = tname "_3"
3351 +- }
3352 +- } else {
3353 +- # print primary/escaped tables
3354 +- if (array_size(table) != 0) {
3355 +- print_table(table, tname "[INAT_OPCODE_TABLE_SIZE]",
3356 +- "0x%02x", 256)
3357 +- etable[eid,0] = tname
3358 +- if (aid >= 0)
3359 +- atable[aid,0] = tname
3360 +- }
3361 +- if (array_size(lptable1) != 0) {
3362 +- print_table(lptable1,tname "_1[INAT_OPCODE_TABLE_SIZE]",
3363 +- "0x%02x", 256)
3364 +- etable[eid,1] = tname "_1"
3365 +- if (aid >= 0)
3366 +- atable[aid,1] = tname "_1"
3367 +- }
3368 +- if (array_size(lptable2) != 0) {
3369 +- print_table(lptable2,tname "_2[INAT_OPCODE_TABLE_SIZE]",
3370 +- "0x%02x", 256)
3371 +- etable[eid,2] = tname "_2"
3372 +- if (aid >= 0)
3373 +- atable[aid,2] = tname "_2"
3374 +- }
3375 +- if (array_size(lptable3) != 0) {
3376 +- print_table(lptable3,tname "_3[INAT_OPCODE_TABLE_SIZE]",
3377 +- "0x%02x", 256)
3378 +- etable[eid,3] = tname "_3"
3379 +- if (aid >= 0)
3380 +- atable[aid,3] = tname "_3"
3381 +- }
3382 +- }
3383 +- print ""
3384 +- clear_vars()
3385 +-}
3386 +-
3387 +-function add_flags(old,new) {
3388 +- if (old && new)
3389 +- return old " | " new
3390 +- else if (old)
3391 +- return old
3392 +- else
3393 +- return new
3394 +-}
3395 +-
3396 +-# convert operands to flags.
3397 +-function convert_operands(count,opnd, i,j,imm,mod)
3398 +-{
3399 +- imm = null
3400 +- mod = null
3401 +- for (j = 1; j <= count; j++) {
3402 +- i = opnd[j]
3403 +- if (match(i, imm_expr) == 1) {
3404 +- if (!imm_flag[i])
3405 +- semantic_error("Unknown imm opnd: " i)
3406 +- if (imm) {
3407 +- if (i != "Ib")
3408 +- semantic_error("Second IMM error")
3409 +- imm = add_flags(imm, "INAT_SCNDIMM")
3410 +- } else
3411 +- imm = imm_flag[i]
3412 +- } else if (match(i, modrm_expr))
3413 +- mod = "INAT_MODRM"
3414 +- }
3415 +- return add_flags(imm, mod)
3416 +-}
3417 +-
3418 +-/^[0-9a-f]+\:/ {
3419 +- if (NR == 1)
3420 +- next
3421 +- # get index
3422 +- idx = "0x" substr($1, 1, index($1,":") - 1)
3423 +- if (idx in table)
3424 +- semantic_error("Redefine " idx " in " tname)
3425 +-
3426 +- # check if escaped opcode
3427 +- if ("escape" == $2) {
3428 +- if ($3 != "#")
3429 +- semantic_error("No escaped name")
3430 +- ref = ""
3431 +- for (i = 4; i <= NF; i++)
3432 +- ref = ref $i
3433 +- if (ref in escape)
3434 +- semantic_error("Redefine escape (" ref ")")
3435 +- escape[ref] = geid
3436 +- geid++
3437 +- table[idx] = "INAT_MAKE_ESCAPE(" escape[ref] ")"
3438 +- next
3439 +- }
3440 +-
3441 +- variant = null
3442 +- # converts
3443 +- i = 2
3444 +- while (i <= NF) {
3445 +- opcode = $(i++)
3446 +- delete opnds
3447 +- ext = null
3448 +- flags = null
3449 +- opnd = null
3450 +- # parse one opcode
3451 +- if (match($i, opnd_expr)) {
3452 +- opnd = $i
3453 +- count = split($(i++), opnds, ",")
3454 +- flags = convert_operands(count, opnds)
3455 +- }
3456 +- if (match($i, ext_expr))
3457 +- ext = $(i++)
3458 +- if (match($i, sep_expr))
3459 +- i++
3460 +- else if (i < NF)
3461 +- semantic_error($i " is not a separator")
3462 +-
3463 +- # check if group opcode
3464 +- if (match(opcode, group_expr)) {
3465 +- if (!(opcode in group)) {
3466 +- group[opcode] = ggid
3467 +- ggid++
3468 +- }
3469 +- flags = add_flags(flags, "INAT_MAKE_GROUP(" group[opcode] ")")
3470 +- }
3471 +- # check force(or default) 64bit
3472 +- if (match(ext, force64_expr))
3473 +- flags = add_flags(flags, "INAT_FORCE64")
3474 +-
3475 +- # check REX prefix
3476 +- if (match(opcode, rex_expr))
3477 +- flags = add_flags(flags, "INAT_MAKE_PREFIX(INAT_PFX_REX)")
3478 +-
3479 +- # check coprocessor escape : TODO
3480 +- if (match(opcode, fpu_expr))
3481 +- flags = add_flags(flags, "INAT_MODRM")
3482 +-
3483 +- # check VEX codes
3484 +- if (match(ext, evexonly_expr))
3485 +- flags = add_flags(flags, "INAT_VEXOK | INAT_EVEXONLY")
3486 +- else if (match(ext, vexonly_expr))
3487 +- flags = add_flags(flags, "INAT_VEXOK | INAT_VEXONLY")
3488 +- else if (match(ext, vexok_expr) || match(opcode, vexok_opcode_expr))
3489 +- flags = add_flags(flags, "INAT_VEXOK")
3490 +-
3491 +- # check prefixes
3492 +- if (match(ext, prefix_expr)) {
3493 +- if (!prefix_num[opcode])
3494 +- semantic_error("Unknown prefix: " opcode)
3495 +- flags = add_flags(flags, "INAT_MAKE_PREFIX(" prefix_num[opcode] ")")
3496 +- }
3497 +- if (length(flags) == 0)
3498 +- continue
3499 +- # check if last prefix
3500 +- if (match(ext, lprefix1_expr)) {
3501 +- lptable1[idx] = add_flags(lptable1[idx],flags)
3502 +- variant = "INAT_VARIANT"
3503 +- }
3504 +- if (match(ext, lprefix2_expr)) {
3505 +- lptable2[idx] = add_flags(lptable2[idx],flags)
3506 +- variant = "INAT_VARIANT"
3507 +- }
3508 +- if (match(ext, lprefix3_expr)) {
3509 +- lptable3[idx] = add_flags(lptable3[idx],flags)
3510 +- variant = "INAT_VARIANT"
3511 +- }
3512 +- if (!match(ext, lprefix_expr)){
3513 +- table[idx] = add_flags(table[idx],flags)
3514 +- }
3515 +- }
3516 +- if (variant)
3517 +- table[idx] = add_flags(table[idx],variant)
3518 +-}
3519 +-
3520 +-END {
3521 +- if (awkchecked != "")
3522 +- exit 1
3523 +- # print escape opcode map's array
3524 +- print "/* Escape opcode map array */"
3525 +- print "const insn_attr_t * const inat_escape_tables[INAT_ESC_MAX + 1]" \
3526 +- "[INAT_LSTPFX_MAX + 1] = {"
3527 +- for (i = 0; i < geid; i++)
3528 +- for (j = 0; j < max_lprefix; j++)
3529 +- if (etable[i,j])
3530 +- print " ["i"]["j"] = "etable[i,j]","
3531 +- print "};\n"
3532 +- # print group opcode map's array
3533 +- print "/* Group opcode map array */"
3534 +- print "const insn_attr_t * const inat_group_tables[INAT_GRP_MAX + 1]"\
3535 +- "[INAT_LSTPFX_MAX + 1] = {"
3536 +- for (i = 0; i < ggid; i++)
3537 +- for (j = 0; j < max_lprefix; j++)
3538 +- if (gtable[i,j])
3539 +- print " ["i"]["j"] = "gtable[i,j]","
3540 +- print "};\n"
3541 +- # print AVX opcode map's array
3542 +- print "/* AVX opcode map array */"
3543 +- print "const insn_attr_t * const inat_avx_tables[X86_VEX_M_MAX + 1]"\
3544 +- "[INAT_LSTPFX_MAX + 1] = {"
3545 +- for (i = 0; i < gaid; i++)
3546 +- for (j = 0; j < max_lprefix; j++)
3547 +- if (atable[i,j])
3548 +- print " ["i"]["j"] = "atable[i,j]","
3549 +- print "};"
3550 +-}
3551 +-
3552 +diff --git a/tools/objtool/arch/x86/insn/inat.c b/tools/objtool/arch/x86/insn/inat.c
3553 +deleted file mode 100644
3554 +index e4bf28e6f4c7..000000000000
3555 +--- a/tools/objtool/arch/x86/insn/inat.c
3556 ++++ /dev/null
3557 +@@ -1,97 +0,0 @@
3558 +-/*
3559 +- * x86 instruction attribute tables
3560 +- *
3561 +- * Written by Masami Hiramatsu <mhiramat@××××××.com>
3562 +- *
3563 +- * This program is free software; you can redistribute it and/or modify
3564 +- * it under the terms of the GNU General Public License as published by
3565 +- * the Free Software Foundation; either version 2 of the License, or
3566 +- * (at your option) any later version.
3567 +- *
3568 +- * This program is distributed in the hope that it will be useful,
3569 +- * but WITHOUT ANY WARRANTY; without even the implied warranty of
3570 +- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3571 +- * GNU General Public License for more details.
3572 +- *
3573 +- * You should have received a copy of the GNU General Public License
3574 +- * along with this program; if not, write to the Free Software
3575 +- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
3576 +- *
3577 +- */
3578 +-#include "insn.h"
3579 +-
3580 +-/* Attribute tables are generated from opcode map */
3581 +-#include "inat-tables.c"
3582 +-
3583 +-/* Attribute search APIs */
3584 +-insn_attr_t inat_get_opcode_attribute(insn_byte_t opcode)
3585 +-{
3586 +- return inat_primary_table[opcode];
3587 +-}
3588 +-
3589 +-int inat_get_last_prefix_id(insn_byte_t last_pfx)
3590 +-{
3591 +- insn_attr_t lpfx_attr;
3592 +-
3593 +- lpfx_attr = inat_get_opcode_attribute(last_pfx);
3594 +- return inat_last_prefix_id(lpfx_attr);
3595 +-}
3596 +-
3597 +-insn_attr_t inat_get_escape_attribute(insn_byte_t opcode, int lpfx_id,
3598 +- insn_attr_t esc_attr)
3599 +-{
3600 +- const insn_attr_t *table;
3601 +- int n;
3602 +-
3603 +- n = inat_escape_id(esc_attr);
3604 +-
3605 +- table = inat_escape_tables[n][0];
3606 +- if (!table)
3607 +- return 0;
3608 +- if (inat_has_variant(table[opcode]) && lpfx_id) {
3609 +- table = inat_escape_tables[n][lpfx_id];
3610 +- if (!table)
3611 +- return 0;
3612 +- }
3613 +- return table[opcode];
3614 +-}
3615 +-
3616 +-insn_attr_t inat_get_group_attribute(insn_byte_t modrm, int lpfx_id,
3617 +- insn_attr_t grp_attr)
3618 +-{
3619 +- const insn_attr_t *table;
3620 +- int n;
3621 +-
3622 +- n = inat_group_id(grp_attr);
3623 +-
3624 +- table = inat_group_tables[n][0];
3625 +- if (!table)
3626 +- return inat_group_common_attribute(grp_attr);
3627 +- if (inat_has_variant(table[X86_MODRM_REG(modrm)]) && lpfx_id) {
3628 +- table = inat_group_tables[n][lpfx_id];
3629 +- if (!table)
3630 +- return inat_group_common_attribute(grp_attr);
3631 +- }
3632 +- return table[X86_MODRM_REG(modrm)] |
3633 +- inat_group_common_attribute(grp_attr);
3634 +-}
3635 +-
3636 +-insn_attr_t inat_get_avx_attribute(insn_byte_t opcode, insn_byte_t vex_m,
3637 +- insn_byte_t vex_p)
3638 +-{
3639 +- const insn_attr_t *table;
3640 +- if (vex_m > X86_VEX_M_MAX || vex_p > INAT_LSTPFX_MAX)
3641 +- return 0;
3642 +- /* At first, this checks the master table */
3643 +- table = inat_avx_tables[vex_m][0];
3644 +- if (!table)
3645 +- return 0;
3646 +- if (!inat_is_group(table[opcode]) && vex_p) {
3647 +- /* If this is not a group, get attribute directly */
3648 +- table = inat_avx_tables[vex_m][vex_p];
3649 +- if (!table)
3650 +- return 0;
3651 +- }
3652 +- return table[opcode];
3653 +-}
3654 +-
3655 +diff --git a/tools/objtool/arch/x86/insn/inat.h b/tools/objtool/arch/x86/insn/inat.h
3656 +deleted file mode 100644
3657 +index 125ecd2a300d..000000000000
3658 +--- a/tools/objtool/arch/x86/insn/inat.h
3659 ++++ /dev/null
3660 +@@ -1,234 +0,0 @@
3661 +-#ifndef _ASM_X86_INAT_H
3662 +-#define _ASM_X86_INAT_H
3663 +-/*
3664 +- * x86 instruction attributes
3665 +- *
3666 +- * Written by Masami Hiramatsu <mhiramat@××××××.com>
3667 +- *
3668 +- * This program is free software; you can redistribute it and/or modify
3669 +- * it under the terms of the GNU General Public License as published by
3670 +- * the Free Software Foundation; either version 2 of the License, or
3671 +- * (at your option) any later version.
3672 +- *
3673 +- * This program is distributed in the hope that it will be useful,
3674 +- * but WITHOUT ANY WARRANTY; without even the implied warranty of
3675 +- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3676 +- * GNU General Public License for more details.
3677 +- *
3678 +- * You should have received a copy of the GNU General Public License
3679 +- * along with this program; if not, write to the Free Software
3680 +- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
3681 +- *
3682 +- */
3683 +-#include "inat_types.h"
3684 +-
3685 +-/*
3686 +- * Internal bits. Don't use bitmasks directly, because these bits are
3687 +- * unstable. You should use checking functions.
3688 +- */
3689 +-
3690 +-#define INAT_OPCODE_TABLE_SIZE 256
3691 +-#define INAT_GROUP_TABLE_SIZE 8
3692 +-
3693 +-/* Legacy last prefixes */
3694 +-#define INAT_PFX_OPNDSZ 1 /* 0x66 */ /* LPFX1 */
3695 +-#define INAT_PFX_REPE 2 /* 0xF3 */ /* LPFX2 */
3696 +-#define INAT_PFX_REPNE 3 /* 0xF2 */ /* LPFX3 */
3697 +-/* Other Legacy prefixes */
3698 +-#define INAT_PFX_LOCK 4 /* 0xF0 */
3699 +-#define INAT_PFX_CS 5 /* 0x2E */
3700 +-#define INAT_PFX_DS 6 /* 0x3E */
3701 +-#define INAT_PFX_ES 7 /* 0x26 */
3702 +-#define INAT_PFX_FS 8 /* 0x64 */
3703 +-#define INAT_PFX_GS 9 /* 0x65 */
3704 +-#define INAT_PFX_SS 10 /* 0x36 */
3705 +-#define INAT_PFX_ADDRSZ 11 /* 0x67 */
3706 +-/* x86-64 REX prefix */
3707 +-#define INAT_PFX_REX 12 /* 0x4X */
3708 +-/* AVX VEX prefixes */
3709 +-#define INAT_PFX_VEX2 13 /* 2-bytes VEX prefix */
3710 +-#define INAT_PFX_VEX3 14 /* 3-bytes VEX prefix */
3711 +-#define INAT_PFX_EVEX 15 /* EVEX prefix */
3712 +-
3713 +-#define INAT_LSTPFX_MAX 3
3714 +-#define INAT_LGCPFX_MAX 11
3715 +-
3716 +-/* Immediate size */
3717 +-#define INAT_IMM_BYTE 1
3718 +-#define INAT_IMM_WORD 2
3719 +-#define INAT_IMM_DWORD 3
3720 +-#define INAT_IMM_QWORD 4
3721 +-#define INAT_IMM_PTR 5
3722 +-#define INAT_IMM_VWORD32 6
3723 +-#define INAT_IMM_VWORD 7
3724 +-
3725 +-/* Legacy prefix */
3726 +-#define INAT_PFX_OFFS 0
3727 +-#define INAT_PFX_BITS 4
3728 +-#define INAT_PFX_MAX ((1 << INAT_PFX_BITS) - 1)
3729 +-#define INAT_PFX_MASK (INAT_PFX_MAX << INAT_PFX_OFFS)
3730 +-/* Escape opcodes */
3731 +-#define INAT_ESC_OFFS (INAT_PFX_OFFS + INAT_PFX_BITS)
3732 +-#define INAT_ESC_BITS 2
3733 +-#define INAT_ESC_MAX ((1 << INAT_ESC_BITS) - 1)
3734 +-#define INAT_ESC_MASK (INAT_ESC_MAX << INAT_ESC_OFFS)
3735 +-/* Group opcodes (1-16) */
3736 +-#define INAT_GRP_OFFS (INAT_ESC_OFFS + INAT_ESC_BITS)
3737 +-#define INAT_GRP_BITS 5
3738 +-#define INAT_GRP_MAX ((1 << INAT_GRP_BITS) - 1)
3739 +-#define INAT_GRP_MASK (INAT_GRP_MAX << INAT_GRP_OFFS)
3740 +-/* Immediates */
3741 +-#define INAT_IMM_OFFS (INAT_GRP_OFFS + INAT_GRP_BITS)
3742 +-#define INAT_IMM_BITS 3
3743 +-#define INAT_IMM_MASK (((1 << INAT_IMM_BITS) - 1) << INAT_IMM_OFFS)
3744 +-/* Flags */
3745 +-#define INAT_FLAG_OFFS (INAT_IMM_OFFS + INAT_IMM_BITS)
3746 +-#define INAT_MODRM (1 << (INAT_FLAG_OFFS))
3747 +-#define INAT_FORCE64 (1 << (INAT_FLAG_OFFS + 1))
3748 +-#define INAT_SCNDIMM (1 << (INAT_FLAG_OFFS + 2))
3749 +-#define INAT_MOFFSET (1 << (INAT_FLAG_OFFS + 3))
3750 +-#define INAT_VARIANT (1 << (INAT_FLAG_OFFS + 4))
3751 +-#define INAT_VEXOK (1 << (INAT_FLAG_OFFS + 5))
3752 +-#define INAT_VEXONLY (1 << (INAT_FLAG_OFFS + 6))
3753 +-#define INAT_EVEXONLY (1 << (INAT_FLAG_OFFS + 7))
3754 +-/* Attribute making macros for attribute tables */
3755 +-#define INAT_MAKE_PREFIX(pfx) (pfx << INAT_PFX_OFFS)
3756 +-#define INAT_MAKE_ESCAPE(esc) (esc << INAT_ESC_OFFS)
3757 +-#define INAT_MAKE_GROUP(grp) ((grp << INAT_GRP_OFFS) | INAT_MODRM)
3758 +-#define INAT_MAKE_IMM(imm) (imm << INAT_IMM_OFFS)
3759 +-
3760 +-/* Attribute search APIs */
3761 +-extern insn_attr_t inat_get_opcode_attribute(insn_byte_t opcode);
3762 +-extern int inat_get_last_prefix_id(insn_byte_t last_pfx);
3763 +-extern insn_attr_t inat_get_escape_attribute(insn_byte_t opcode,
3764 +- int lpfx_id,
3765 +- insn_attr_t esc_attr);
3766 +-extern insn_attr_t inat_get_group_attribute(insn_byte_t modrm,
3767 +- int lpfx_id,
3768 +- insn_attr_t esc_attr);
3769 +-extern insn_attr_t inat_get_avx_attribute(insn_byte_t opcode,
3770 +- insn_byte_t vex_m,
3771 +- insn_byte_t vex_pp);
3772 +-
3773 +-/* Attribute checking functions */
3774 +-static inline int inat_is_legacy_prefix(insn_attr_t attr)
3775 +-{
3776 +- attr &= INAT_PFX_MASK;
3777 +- return attr && attr <= INAT_LGCPFX_MAX;
3778 +-}
3779 +-
3780 +-static inline int inat_is_address_size_prefix(insn_attr_t attr)
3781 +-{
3782 +- return (attr & INAT_PFX_MASK) == INAT_PFX_ADDRSZ;
3783 +-}
3784 +-
3785 +-static inline int inat_is_operand_size_prefix(insn_attr_t attr)
3786 +-{
3787 +- return (attr & INAT_PFX_MASK) == INAT_PFX_OPNDSZ;
3788 +-}
3789 +-
3790 +-static inline int inat_is_rex_prefix(insn_attr_t attr)
3791 +-{
3792 +- return (attr & INAT_PFX_MASK) == INAT_PFX_REX;
3793 +-}
3794 +-
3795 +-static inline int inat_last_prefix_id(insn_attr_t attr)
3796 +-{
3797 +- if ((attr & INAT_PFX_MASK) > INAT_LSTPFX_MAX)
3798 +- return 0;
3799 +- else
3800 +- return attr & INAT_PFX_MASK;
3801 +-}
3802 +-
3803 +-static inline int inat_is_vex_prefix(insn_attr_t attr)
3804 +-{
3805 +- attr &= INAT_PFX_MASK;
3806 +- return attr == INAT_PFX_VEX2 || attr == INAT_PFX_VEX3 ||
3807 +- attr == INAT_PFX_EVEX;
3808 +-}
3809 +-
3810 +-static inline int inat_is_evex_prefix(insn_attr_t attr)
3811 +-{
3812 +- return (attr & INAT_PFX_MASK) == INAT_PFX_EVEX;
3813 +-}
3814 +-
3815 +-static inline int inat_is_vex3_prefix(insn_attr_t attr)
3816 +-{
3817 +- return (attr & INAT_PFX_MASK) == INAT_PFX_VEX3;
3818 +-}
3819 +-
3820 +-static inline int inat_is_escape(insn_attr_t attr)
3821 +-{
3822 +- return attr & INAT_ESC_MASK;
3823 +-}
3824 +-
3825 +-static inline int inat_escape_id(insn_attr_t attr)
3826 +-{
3827 +- return (attr & INAT_ESC_MASK) >> INAT_ESC_OFFS;
3828 +-}
3829 +-
3830 +-static inline int inat_is_group(insn_attr_t attr)
3831 +-{
3832 +- return attr & INAT_GRP_MASK;
3833 +-}
3834 +-
3835 +-static inline int inat_group_id(insn_attr_t attr)
3836 +-{
3837 +- return (attr & INAT_GRP_MASK) >> INAT_GRP_OFFS;
3838 +-}
3839 +-
3840 +-static inline int inat_group_common_attribute(insn_attr_t attr)
3841 +-{
3842 +- return attr & ~INAT_GRP_MASK;
3843 +-}
3844 +-
3845 +-static inline int inat_has_immediate(insn_attr_t attr)
3846 +-{
3847 +- return attr & INAT_IMM_MASK;
3848 +-}
3849 +-
3850 +-static inline int inat_immediate_size(insn_attr_t attr)
3851 +-{
3852 +- return (attr & INAT_IMM_MASK) >> INAT_IMM_OFFS;
3853 +-}
3854 +-
3855 +-static inline int inat_has_modrm(insn_attr_t attr)
3856 +-{
3857 +- return attr & INAT_MODRM;
3858 +-}
3859 +-
3860 +-static inline int inat_is_force64(insn_attr_t attr)
3861 +-{
3862 +- return attr & INAT_FORCE64;
3863 +-}
3864 +-
3865 +-static inline int inat_has_second_immediate(insn_attr_t attr)
3866 +-{
3867 +- return attr & INAT_SCNDIMM;
3868 +-}
3869 +-
3870 +-static inline int inat_has_moffset(insn_attr_t attr)
3871 +-{
3872 +- return attr & INAT_MOFFSET;
3873 +-}
3874 +-
3875 +-static inline int inat_has_variant(insn_attr_t attr)
3876 +-{
3877 +- return attr & INAT_VARIANT;
3878 +-}
3879 +-
3880 +-static inline int inat_accept_vex(insn_attr_t attr)
3881 +-{
3882 +- return attr & INAT_VEXOK;
3883 +-}
3884 +-
3885 +-static inline int inat_must_vex(insn_attr_t attr)
3886 +-{
3887 +- return attr & (INAT_VEXONLY | INAT_EVEXONLY);
3888 +-}
3889 +-
3890 +-static inline int inat_must_evex(insn_attr_t attr)
3891 +-{
3892 +- return attr & INAT_EVEXONLY;
3893 +-}
3894 +-#endif
3895 +diff --git a/tools/objtool/arch/x86/insn/inat_types.h b/tools/objtool/arch/x86/insn/inat_types.h
3896 +deleted file mode 100644
3897 +index cb3c20ce39cf..000000000000
3898 +--- a/tools/objtool/arch/x86/insn/inat_types.h
3899 ++++ /dev/null
3900 +@@ -1,29 +0,0 @@
3901 +-#ifndef _ASM_X86_INAT_TYPES_H
3902 +-#define _ASM_X86_INAT_TYPES_H
3903 +-/*
3904 +- * x86 instruction attributes
3905 +- *
3906 +- * Written by Masami Hiramatsu <mhiramat@××××××.com>
3907 +- *
3908 +- * This program is free software; you can redistribute it and/or modify
3909 +- * it under the terms of the GNU General Public License as published by
3910 +- * the Free Software Foundation; either version 2 of the License, or
3911 +- * (at your option) any later version.
3912 +- *
3913 +- * This program is distributed in the hope that it will be useful,
3914 +- * but WITHOUT ANY WARRANTY; without even the implied warranty of
3915 +- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3916 +- * GNU General Public License for more details.
3917 +- *
3918 +- * You should have received a copy of the GNU General Public License
3919 +- * along with this program; if not, write to the Free Software
3920 +- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
3921 +- *
3922 +- */
3923 +-
3924 +-/* Instruction attributes */
3925 +-typedef unsigned int insn_attr_t;
3926 +-typedef unsigned char insn_byte_t;
3927 +-typedef signed int insn_value_t;
3928 +-
3929 +-#endif
3930 +diff --git a/tools/objtool/arch/x86/insn/insn.c b/tools/objtool/arch/x86/insn/insn.c
3931 +deleted file mode 100644
3932 +index ca983e2bea8b..000000000000
3933 +--- a/tools/objtool/arch/x86/insn/insn.c
3934 ++++ /dev/null
3935 +@@ -1,606 +0,0 @@
3936 +-/*
3937 +- * x86 instruction analysis
3938 +- *
3939 +- * This program is free software; you can redistribute it and/or modify
3940 +- * it under the terms of the GNU General Public License as published by
3941 +- * the Free Software Foundation; either version 2 of the License, or
3942 +- * (at your option) any later version.
3943 +- *
3944 +- * This program is distributed in the hope that it will be useful,
3945 +- * but WITHOUT ANY WARRANTY; without even the implied warranty of
3946 +- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3947 +- * GNU General Public License for more details.
3948 +- *
3949 +- * You should have received a copy of the GNU General Public License
3950 +- * along with this program; if not, write to the Free Software
3951 +- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
3952 +- *
3953 +- * Copyright (C) IBM Corporation, 2002, 2004, 2009
3954 +- */
3955 +-
3956 +-#ifdef __KERNEL__
3957 +-#include <linux/string.h>
3958 +-#else
3959 +-#include <string.h>
3960 +-#endif
3961 +-#include "inat.h"
3962 +-#include "insn.h"
3963 +-
3964 +-/* Verify next sizeof(t) bytes can be on the same instruction */
3965 +-#define validate_next(t, insn, n) \
3966 +- ((insn)->next_byte + sizeof(t) + n <= (insn)->end_kaddr)
3967 +-
3968 +-#define __get_next(t, insn) \
3969 +- ({ t r = *(t*)insn->next_byte; insn->next_byte += sizeof(t); r; })
3970 +-
3971 +-#define __peek_nbyte_next(t, insn, n) \
3972 +- ({ t r = *(t*)((insn)->next_byte + n); r; })
3973 +-
3974 +-#define get_next(t, insn) \
3975 +- ({ if (unlikely(!validate_next(t, insn, 0))) goto err_out; __get_next(t, insn); })
3976 +-
3977 +-#define peek_nbyte_next(t, insn, n) \
3978 +- ({ if (unlikely(!validate_next(t, insn, n))) goto err_out; __peek_nbyte_next(t, insn, n); })
3979 +-
3980 +-#define peek_next(t, insn) peek_nbyte_next(t, insn, 0)
3981 +-
3982 +-/**
3983 +- * insn_init() - initialize struct insn
3984 +- * @insn: &struct insn to be initialized
3985 +- * @kaddr: address (in kernel memory) of instruction (or copy thereof)
3986 +- * @x86_64: !0 for 64-bit kernel or 64-bit app
3987 +- */
3988 +-void insn_init(struct insn *insn, const void *kaddr, int buf_len, int x86_64)
3989 +-{
3990 +- /*
3991 +- * Instructions longer than MAX_INSN_SIZE (15 bytes) are invalid
3992 +- * even if the input buffer is long enough to hold them.
3993 +- */
3994 +- if (buf_len > MAX_INSN_SIZE)
3995 +- buf_len = MAX_INSN_SIZE;
3996 +-
3997 +- memset(insn, 0, sizeof(*insn));
3998 +- insn->kaddr = kaddr;
3999 +- insn->end_kaddr = kaddr + buf_len;
4000 +- insn->next_byte = kaddr;
4001 +- insn->x86_64 = x86_64 ? 1 : 0;
4002 +- insn->opnd_bytes = 4;
4003 +- if (x86_64)
4004 +- insn->addr_bytes = 8;
4005 +- else
4006 +- insn->addr_bytes = 4;
4007 +-}
4008 +-
4009 +-/**
4010 +- * insn_get_prefixes - scan x86 instruction prefix bytes
4011 +- * @insn: &struct insn containing instruction
4012 +- *
4013 +- * Populates the @insn->prefixes bitmap, and updates @insn->next_byte
4014 +- * to point to the (first) opcode. No effect if @insn->prefixes.got
4015 +- * is already set.
4016 +- */
4017 +-void insn_get_prefixes(struct insn *insn)
4018 +-{
4019 +- struct insn_field *prefixes = &insn->prefixes;
4020 +- insn_attr_t attr;
4021 +- insn_byte_t b, lb;
4022 +- int i, nb;
4023 +-
4024 +- if (prefixes->got)
4025 +- return;
4026 +-
4027 +- nb = 0;
4028 +- lb = 0;
4029 +- b = peek_next(insn_byte_t, insn);
4030 +- attr = inat_get_opcode_attribute(b);
4031 +- while (inat_is_legacy_prefix(attr)) {
4032 +- /* Skip if same prefix */
4033 +- for (i = 0; i < nb; i++)
4034 +- if (prefixes->bytes[i] == b)
4035 +- goto found;
4036 +- if (nb == 4)
4037 +- /* Invalid instruction */
4038 +- break;
4039 +- prefixes->bytes[nb++] = b;
4040 +- if (inat_is_address_size_prefix(attr)) {
4041 +- /* address size switches 2/4 or 4/8 */
4042 +- if (insn->x86_64)
4043 +- insn->addr_bytes ^= 12;
4044 +- else
4045 +- insn->addr_bytes ^= 6;
4046 +- } else if (inat_is_operand_size_prefix(attr)) {
4047 +- /* oprand size switches 2/4 */
4048 +- insn->opnd_bytes ^= 6;
4049 +- }
4050 +-found:
4051 +- prefixes->nbytes++;
4052 +- insn->next_byte++;
4053 +- lb = b;
4054 +- b = peek_next(insn_byte_t, insn);
4055 +- attr = inat_get_opcode_attribute(b);
4056 +- }
4057 +- /* Set the last prefix */
4058 +- if (lb && lb != insn->prefixes.bytes[3]) {
4059 +- if (unlikely(insn->prefixes.bytes[3])) {
4060 +- /* Swap the last prefix */
4061 +- b = insn->prefixes.bytes[3];
4062 +- for (i = 0; i < nb; i++)
4063 +- if (prefixes->bytes[i] == lb)
4064 +- prefixes->bytes[i] = b;
4065 +- }
4066 +- insn->prefixes.bytes[3] = lb;
4067 +- }
4068 +-
4069 +- /* Decode REX prefix */
4070 +- if (insn->x86_64) {
4071 +- b = peek_next(insn_byte_t, insn);
4072 +- attr = inat_get_opcode_attribute(b);
4073 +- if (inat_is_rex_prefix(attr)) {
4074 +- insn->rex_prefix.value = b;
4075 +- insn->rex_prefix.nbytes = 1;
4076 +- insn->next_byte++;
4077 +- if (X86_REX_W(b))
4078 +- /* REX.W overrides opnd_size */
4079 +- insn->opnd_bytes = 8;
4080 +- }
4081 +- }
4082 +- insn->rex_prefix.got = 1;
4083 +-
4084 +- /* Decode VEX prefix */
4085 +- b = peek_next(insn_byte_t, insn);
4086 +- attr = inat_get_opcode_attribute(b);
4087 +- if (inat_is_vex_prefix(attr)) {
4088 +- insn_byte_t b2 = peek_nbyte_next(insn_byte_t, insn, 1);
4089 +- if (!insn->x86_64) {
4090 +- /*
4091 +- * In 32-bits mode, if the [7:6] bits (mod bits of
4092 +- * ModRM) on the second byte are not 11b, it is
4093 +- * LDS or LES or BOUND.
4094 +- */
4095 +- if (X86_MODRM_MOD(b2) != 3)
4096 +- goto vex_end;
4097 +- }
4098 +- insn->vex_prefix.bytes[0] = b;
4099 +- insn->vex_prefix.bytes[1] = b2;
4100 +- if (inat_is_evex_prefix(attr)) {
4101 +- b2 = peek_nbyte_next(insn_byte_t, insn, 2);
4102 +- insn->vex_prefix.bytes[2] = b2;
4103 +- b2 = peek_nbyte_next(insn_byte_t, insn, 3);
4104 +- insn->vex_prefix.bytes[3] = b2;
4105 +- insn->vex_prefix.nbytes = 4;
4106 +- insn->next_byte += 4;
4107 +- if (insn->x86_64 && X86_VEX_W(b2))
4108 +- /* VEX.W overrides opnd_size */
4109 +- insn->opnd_bytes = 8;
4110 +- } else if (inat_is_vex3_prefix(attr)) {
4111 +- b2 = peek_nbyte_next(insn_byte_t, insn, 2);
4112 +- insn->vex_prefix.bytes[2] = b2;
4113 +- insn->vex_prefix.nbytes = 3;
4114 +- insn->next_byte += 3;
4115 +- if (insn->x86_64 && X86_VEX_W(b2))
4116 +- /* VEX.W overrides opnd_size */
4117 +- insn->opnd_bytes = 8;
4118 +- } else {
4119 +- /*
4120 +- * For VEX2, fake VEX3-like byte#2.
4121 +- * Makes it easier to decode vex.W, vex.vvvv,
4122 +- * vex.L and vex.pp. Masking with 0x7f sets vex.W == 0.
4123 +- */
4124 +- insn->vex_prefix.bytes[2] = b2 & 0x7f;
4125 +- insn->vex_prefix.nbytes = 2;
4126 +- insn->next_byte += 2;
4127 +- }
4128 +- }
4129 +-vex_end:
4130 +- insn->vex_prefix.got = 1;
4131 +-
4132 +- prefixes->got = 1;
4133 +-
4134 +-err_out:
4135 +- return;
4136 +-}
4137 +-
4138 +-/**
4139 +- * insn_get_opcode - collect opcode(s)
4140 +- * @insn: &struct insn containing instruction
4141 +- *
4142 +- * Populates @insn->opcode, updates @insn->next_byte to point past the
4143 +- * opcode byte(s), and set @insn->attr (except for groups).
4144 +- * If necessary, first collects any preceding (prefix) bytes.
4145 +- * Sets @insn->opcode.value = opcode1. No effect if @insn->opcode.got
4146 +- * is already 1.
4147 +- */
4148 +-void insn_get_opcode(struct insn *insn)
4149 +-{
4150 +- struct insn_field *opcode = &insn->opcode;
4151 +- insn_byte_t op;
4152 +- int pfx_id;
4153 +- if (opcode->got)
4154 +- return;
4155 +- if (!insn->prefixes.got)
4156 +- insn_get_prefixes(insn);
4157 +-
4158 +- /* Get first opcode */
4159 +- op = get_next(insn_byte_t, insn);
4160 +- opcode->bytes[0] = op;
4161 +- opcode->nbytes = 1;
4162 +-
4163 +- /* Check if there is VEX prefix or not */
4164 +- if (insn_is_avx(insn)) {
4165 +- insn_byte_t m, p;
4166 +- m = insn_vex_m_bits(insn);
4167 +- p = insn_vex_p_bits(insn);
4168 +- insn->attr = inat_get_avx_attribute(op, m, p);
4169 +- if ((inat_must_evex(insn->attr) && !insn_is_evex(insn)) ||
4170 +- (!inat_accept_vex(insn->attr) &&
4171 +- !inat_is_group(insn->attr)))
4172 +- insn->attr = 0; /* This instruction is bad */
4173 +- goto end; /* VEX has only 1 byte for opcode */
4174 +- }
4175 +-
4176 +- insn->attr = inat_get_opcode_attribute(op);
4177 +- while (inat_is_escape(insn->attr)) {
4178 +- /* Get escaped opcode */
4179 +- op = get_next(insn_byte_t, insn);
4180 +- opcode->bytes[opcode->nbytes++] = op;
4181 +- pfx_id = insn_last_prefix_id(insn);
4182 +- insn->attr = inat_get_escape_attribute(op, pfx_id, insn->attr);
4183 +- }
4184 +- if (inat_must_vex(insn->attr))
4185 +- insn->attr = 0; /* This instruction is bad */
4186 +-end:
4187 +- opcode->got = 1;
4188 +-
4189 +-err_out:
4190 +- return;
4191 +-}
4192 +-
4193 +-/**
4194 +- * insn_get_modrm - collect ModRM byte, if any
4195 +- * @insn: &struct insn containing instruction
4196 +- *
4197 +- * Populates @insn->modrm and updates @insn->next_byte to point past the
4198 +- * ModRM byte, if any. If necessary, first collects the preceding bytes
4199 +- * (prefixes and opcode(s)). No effect if @insn->modrm.got is already 1.
4200 +- */
4201 +-void insn_get_modrm(struct insn *insn)
4202 +-{
4203 +- struct insn_field *modrm = &insn->modrm;
4204 +- insn_byte_t pfx_id, mod;
4205 +- if (modrm->got)
4206 +- return;
4207 +- if (!insn->opcode.got)
4208 +- insn_get_opcode(insn);
4209 +-
4210 +- if (inat_has_modrm(insn->attr)) {
4211 +- mod = get_next(insn_byte_t, insn);
4212 +- modrm->value = mod;
4213 +- modrm->nbytes = 1;
4214 +- if (inat_is_group(insn->attr)) {
4215 +- pfx_id = insn_last_prefix_id(insn);
4216 +- insn->attr = inat_get_group_attribute(mod, pfx_id,
4217 +- insn->attr);
4218 +- if (insn_is_avx(insn) && !inat_accept_vex(insn->attr))
4219 +- insn->attr = 0; /* This is bad */
4220 +- }
4221 +- }
4222 +-
4223 +- if (insn->x86_64 && inat_is_force64(insn->attr))
4224 +- insn->opnd_bytes = 8;
4225 +- modrm->got = 1;
4226 +-
4227 +-err_out:
4228 +- return;
4229 +-}
4230 +-
4231 +-
4232 +-/**
4233 +- * insn_rip_relative() - Does instruction use RIP-relative addressing mode?
4234 +- * @insn: &struct insn containing instruction
4235 +- *
4236 +- * If necessary, first collects the instruction up to and including the
4237 +- * ModRM byte. No effect if @insn->x86_64 is 0.
4238 +- */
4239 +-int insn_rip_relative(struct insn *insn)
4240 +-{
4241 +- struct insn_field *modrm = &insn->modrm;
4242 +-
4243 +- if (!insn->x86_64)
4244 +- return 0;
4245 +- if (!modrm->got)
4246 +- insn_get_modrm(insn);
4247 +- /*
4248 +- * For rip-relative instructions, the mod field (top 2 bits)
4249 +- * is zero and the r/m field (bottom 3 bits) is 0x5.
4250 +- */
4251 +- return (modrm->nbytes && (modrm->value & 0xc7) == 0x5);
4252 +-}
4253 +-
4254 +-/**
4255 +- * insn_get_sib() - Get the SIB byte of instruction
4256 +- * @insn: &struct insn containing instruction
4257 +- *
4258 +- * If necessary, first collects the instruction up to and including the
4259 +- * ModRM byte.
4260 +- */
4261 +-void insn_get_sib(struct insn *insn)
4262 +-{
4263 +- insn_byte_t modrm;
4264 +-
4265 +- if (insn->sib.got)
4266 +- return;
4267 +- if (!insn->modrm.got)
4268 +- insn_get_modrm(insn);
4269 +- if (insn->modrm.nbytes) {
4270 +- modrm = (insn_byte_t)insn->modrm.value;
4271 +- if (insn->addr_bytes != 2 &&
4272 +- X86_MODRM_MOD(modrm) != 3 && X86_MODRM_RM(modrm) == 4) {
4273 +- insn->sib.value = get_next(insn_byte_t, insn);
4274 +- insn->sib.nbytes = 1;
4275 +- }
4276 +- }
4277 +- insn->sib.got = 1;
4278 +-
4279 +-err_out:
4280 +- return;
4281 +-}
4282 +-
4283 +-
4284 +-/**
4285 +- * insn_get_displacement() - Get the displacement of instruction
4286 +- * @insn: &struct insn containing instruction
4287 +- *
4288 +- * If necessary, first collects the instruction up to and including the
4289 +- * SIB byte.
4290 +- * Displacement value is sign-expanded.
4291 +- */
4292 +-void insn_get_displacement(struct insn *insn)
4293 +-{
4294 +- insn_byte_t mod, rm, base;
4295 +-
4296 +- if (insn->displacement.got)
4297 +- return;
4298 +- if (!insn->sib.got)
4299 +- insn_get_sib(insn);
4300 +- if (insn->modrm.nbytes) {
4301 +- /*
4302 +- * Interpreting the modrm byte:
4303 +- * mod = 00 - no displacement fields (exceptions below)
4304 +- * mod = 01 - 1-byte displacement field
4305 +- * mod = 10 - displacement field is 4 bytes, or 2 bytes if
4306 +- * address size = 2 (0x67 prefix in 32-bit mode)
4307 +- * mod = 11 - no memory operand
4308 +- *
4309 +- * If address size = 2...
4310 +- * mod = 00, r/m = 110 - displacement field is 2 bytes
4311 +- *
4312 +- * If address size != 2...
4313 +- * mod != 11, r/m = 100 - SIB byte exists
4314 +- * mod = 00, SIB base = 101 - displacement field is 4 bytes
4315 +- * mod = 00, r/m = 101 - rip-relative addressing, displacement
4316 +- * field is 4 bytes
4317 +- */
4318 +- mod = X86_MODRM_MOD(insn->modrm.value);
4319 +- rm = X86_MODRM_RM(insn->modrm.value);
4320 +- base = X86_SIB_BASE(insn->sib.value);
4321 +- if (mod == 3)
4322 +- goto out;
4323 +- if (mod == 1) {
4324 +- insn->displacement.value = get_next(signed char, insn);
4325 +- insn->displacement.nbytes = 1;
4326 +- } else if (insn->addr_bytes == 2) {
4327 +- if ((mod == 0 && rm == 6) || mod == 2) {
4328 +- insn->displacement.value =
4329 +- get_next(short, insn);
4330 +- insn->displacement.nbytes = 2;
4331 +- }
4332 +- } else {
4333 +- if ((mod == 0 && rm == 5) || mod == 2 ||
4334 +- (mod == 0 && base == 5)) {
4335 +- insn->displacement.value = get_next(int, insn);
4336 +- insn->displacement.nbytes = 4;
4337 +- }
4338 +- }
4339 +- }
4340 +-out:
4341 +- insn->displacement.got = 1;
4342 +-
4343 +-err_out:
4344 +- return;
4345 +-}
4346 +-
4347 +-/* Decode moffset16/32/64. Return 0 if failed */
4348 +-static int __get_moffset(struct insn *insn)
4349 +-{
4350 +- switch (insn->addr_bytes) {
4351 +- case 2:
4352 +- insn->moffset1.value = get_next(short, insn);
4353 +- insn->moffset1.nbytes = 2;
4354 +- break;
4355 +- case 4:
4356 +- insn->moffset1.value = get_next(int, insn);
4357 +- insn->moffset1.nbytes = 4;
4358 +- break;
4359 +- case 8:
4360 +- insn->moffset1.value = get_next(int, insn);
4361 +- insn->moffset1.nbytes = 4;
4362 +- insn->moffset2.value = get_next(int, insn);
4363 +- insn->moffset2.nbytes = 4;
4364 +- break;
4365 +- default: /* opnd_bytes must be modified manually */
4366 +- goto err_out;
4367 +- }
4368 +- insn->moffset1.got = insn->moffset2.got = 1;
4369 +-
4370 +- return 1;
4371 +-
4372 +-err_out:
4373 +- return 0;
4374 +-}
4375 +-
4376 +-/* Decode imm v32(Iz). Return 0 if failed */
4377 +-static int __get_immv32(struct insn *insn)
4378 +-{
4379 +- switch (insn->opnd_bytes) {
4380 +- case 2:
4381 +- insn->immediate.value = get_next(short, insn);
4382 +- insn->immediate.nbytes = 2;
4383 +- break;
4384 +- case 4:
4385 +- case 8:
4386 +- insn->immediate.value = get_next(int, insn);
4387 +- insn->immediate.nbytes = 4;
4388 +- break;
4389 +- default: /* opnd_bytes must be modified manually */
4390 +- goto err_out;
4391 +- }
4392 +-
4393 +- return 1;
4394 +-
4395 +-err_out:
4396 +- return 0;
4397 +-}
4398 +-
4399 +-/* Decode imm v64(Iv/Ov), Return 0 if failed */
4400 +-static int __get_immv(struct insn *insn)
4401 +-{
4402 +- switch (insn->opnd_bytes) {
4403 +- case 2:
4404 +- insn->immediate1.value = get_next(short, insn);
4405 +- insn->immediate1.nbytes = 2;
4406 +- break;
4407 +- case 4:
4408 +- insn->immediate1.value = get_next(int, insn);
4409 +- insn->immediate1.nbytes = 4;
4410 +- break;
4411 +- case 8:
4412 +- insn->immediate1.value = get_next(int, insn);
4413 +- insn->immediate1.nbytes = 4;
4414 +- insn->immediate2.value = get_next(int, insn);
4415 +- insn->immediate2.nbytes = 4;
4416 +- break;
4417 +- default: /* opnd_bytes must be modified manually */
4418 +- goto err_out;
4419 +- }
4420 +- insn->immediate1.got = insn->immediate2.got = 1;
4421 +-
4422 +- return 1;
4423 +-err_out:
4424 +- return 0;
4425 +-}
4426 +-
4427 +-/* Decode ptr16:16/32(Ap) */
4428 +-static int __get_immptr(struct insn *insn)
4429 +-{
4430 +- switch (insn->opnd_bytes) {
4431 +- case 2:
4432 +- insn->immediate1.value = get_next(short, insn);
4433 +- insn->immediate1.nbytes = 2;
4434 +- break;
4435 +- case 4:
4436 +- insn->immediate1.value = get_next(int, insn);
4437 +- insn->immediate1.nbytes = 4;
4438 +- break;
4439 +- case 8:
4440 +- /* ptr16:64 is not exist (no segment) */
4441 +- return 0;
4442 +- default: /* opnd_bytes must be modified manually */
4443 +- goto err_out;
4444 +- }
4445 +- insn->immediate2.value = get_next(unsigned short, insn);
4446 +- insn->immediate2.nbytes = 2;
4447 +- insn->immediate1.got = insn->immediate2.got = 1;
4448 +-
4449 +- return 1;
4450 +-err_out:
4451 +- return 0;
4452 +-}
4453 +-
4454 +-/**
4455 +- * insn_get_immediate() - Get the immediates of instruction
4456 +- * @insn: &struct insn containing instruction
4457 +- *
4458 +- * If necessary, first collects the instruction up to and including the
4459 +- * displacement bytes.
4460 +- * Basically, most of immediates are sign-expanded. Unsigned-value can be
4461 +- * get by bit masking with ((1 << (nbytes * 8)) - 1)
4462 +- */
4463 +-void insn_get_immediate(struct insn *insn)
4464 +-{
4465 +- if (insn->immediate.got)
4466 +- return;
4467 +- if (!insn->displacement.got)
4468 +- insn_get_displacement(insn);
4469 +-
4470 +- if (inat_has_moffset(insn->attr)) {
4471 +- if (!__get_moffset(insn))
4472 +- goto err_out;
4473 +- goto done;
4474 +- }
4475 +-
4476 +- if (!inat_has_immediate(insn->attr))
4477 +- /* no immediates */
4478 +- goto done;
4479 +-
4480 +- switch (inat_immediate_size(insn->attr)) {
4481 +- case INAT_IMM_BYTE:
4482 +- insn->immediate.value = get_next(signed char, insn);
4483 +- insn->immediate.nbytes = 1;
4484 +- break;
4485 +- case INAT_IMM_WORD:
4486 +- insn->immediate.value = get_next(short, insn);
4487 +- insn->immediate.nbytes = 2;
4488 +- break;
4489 +- case INAT_IMM_DWORD:
4490 +- insn->immediate.value = get_next(int, insn);
4491 +- insn->immediate.nbytes = 4;
4492 +- break;
4493 +- case INAT_IMM_QWORD:
4494 +- insn->immediate1.value = get_next(int, insn);
4495 +- insn->immediate1.nbytes = 4;
4496 +- insn->immediate2.value = get_next(int, insn);
4497 +- insn->immediate2.nbytes = 4;
4498 +- break;
4499 +- case INAT_IMM_PTR:
4500 +- if (!__get_immptr(insn))
4501 +- goto err_out;
4502 +- break;
4503 +- case INAT_IMM_VWORD32:
4504 +- if (!__get_immv32(insn))
4505 +- goto err_out;
4506 +- break;
4507 +- case INAT_IMM_VWORD:
4508 +- if (!__get_immv(insn))
4509 +- goto err_out;
4510 +- break;
4511 +- default:
4512 +- /* Here, insn must have an immediate, but failed */
4513 +- goto err_out;
4514 +- }
4515 +- if (inat_has_second_immediate(insn->attr)) {
4516 +- insn->immediate2.value = get_next(signed char, insn);
4517 +- insn->immediate2.nbytes = 1;
4518 +- }
4519 +-done:
4520 +- insn->immediate.got = 1;
4521 +-
4522 +-err_out:
4523 +- return;
4524 +-}
4525 +-
4526 +-/**
4527 +- * insn_get_length() - Get the length of instruction
4528 +- * @insn: &struct insn containing instruction
4529 +- *
4530 +- * If necessary, first collects the instruction up to and including the
4531 +- * immediates bytes.
4532 +- */
4533 +-void insn_get_length(struct insn *insn)
4534 +-{
4535 +- if (insn->length)
4536 +- return;
4537 +- if (!insn->immediate.got)
4538 +- insn_get_immediate(insn);
4539 +- insn->length = (unsigned char)((unsigned long)insn->next_byte
4540 +- - (unsigned long)insn->kaddr);
4541 +-}
4542 +diff --git a/tools/objtool/arch/x86/insn/insn.h b/tools/objtool/arch/x86/insn/insn.h
4543 +deleted file mode 100644
4544 +index e23578c7b1be..000000000000
4545 +--- a/tools/objtool/arch/x86/insn/insn.h
4546 ++++ /dev/null
4547 +@@ -1,211 +0,0 @@
4548 +-#ifndef _ASM_X86_INSN_H
4549 +-#define _ASM_X86_INSN_H
4550 +-/*
4551 +- * x86 instruction analysis
4552 +- *
4553 +- * This program is free software; you can redistribute it and/or modify
4554 +- * it under the terms of the GNU General Public License as published by
4555 +- * the Free Software Foundation; either version 2 of the License, or
4556 +- * (at your option) any later version.
4557 +- *
4558 +- * This program is distributed in the hope that it will be useful,
4559 +- * but WITHOUT ANY WARRANTY; without even the implied warranty of
4560 +- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4561 +- * GNU General Public License for more details.
4562 +- *
4563 +- * You should have received a copy of the GNU General Public License
4564 +- * along with this program; if not, write to the Free Software
4565 +- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
4566 +- *
4567 +- * Copyright (C) IBM Corporation, 2009
4568 +- */
4569 +-
4570 +-/* insn_attr_t is defined in inat.h */
4571 +-#include "inat.h"
4572 +-
4573 +-struct insn_field {
4574 +- union {
4575 +- insn_value_t value;
4576 +- insn_byte_t bytes[4];
4577 +- };
4578 +- /* !0 if we've run insn_get_xxx() for this field */
4579 +- unsigned char got;
4580 +- unsigned char nbytes;
4581 +-};
4582 +-
4583 +-struct insn {
4584 +- struct insn_field prefixes; /*
4585 +- * Prefixes
4586 +- * prefixes.bytes[3]: last prefix
4587 +- */
4588 +- struct insn_field rex_prefix; /* REX prefix */
4589 +- struct insn_field vex_prefix; /* VEX prefix */
4590 +- struct insn_field opcode; /*
4591 +- * opcode.bytes[0]: opcode1
4592 +- * opcode.bytes[1]: opcode2
4593 +- * opcode.bytes[2]: opcode3
4594 +- */
4595 +- struct insn_field modrm;
4596 +- struct insn_field sib;
4597 +- struct insn_field displacement;
4598 +- union {
4599 +- struct insn_field immediate;
4600 +- struct insn_field moffset1; /* for 64bit MOV */
4601 +- struct insn_field immediate1; /* for 64bit imm or off16/32 */
4602 +- };
4603 +- union {
4604 +- struct insn_field moffset2; /* for 64bit MOV */
4605 +- struct insn_field immediate2; /* for 64bit imm or seg16 */
4606 +- };
4607 +-
4608 +- insn_attr_t attr;
4609 +- unsigned char opnd_bytes;
4610 +- unsigned char addr_bytes;
4611 +- unsigned char length;
4612 +- unsigned char x86_64;
4613 +-
4614 +- const insn_byte_t *kaddr; /* kernel address of insn to analyze */
4615 +- const insn_byte_t *end_kaddr; /* kernel address of last insn in buffer */
4616 +- const insn_byte_t *next_byte;
4617 +-};
4618 +-
4619 +-#define MAX_INSN_SIZE 15
4620 +-
4621 +-#define X86_MODRM_MOD(modrm) (((modrm) & 0xc0) >> 6)
4622 +-#define X86_MODRM_REG(modrm) (((modrm) & 0x38) >> 3)
4623 +-#define X86_MODRM_RM(modrm) ((modrm) & 0x07)
4624 +-
4625 +-#define X86_SIB_SCALE(sib) (((sib) & 0xc0) >> 6)
4626 +-#define X86_SIB_INDEX(sib) (((sib) & 0x38) >> 3)
4627 +-#define X86_SIB_BASE(sib) ((sib) & 0x07)
4628 +-
4629 +-#define X86_REX_W(rex) ((rex) & 8)
4630 +-#define X86_REX_R(rex) ((rex) & 4)
4631 +-#define X86_REX_X(rex) ((rex) & 2)
4632 +-#define X86_REX_B(rex) ((rex) & 1)
4633 +-
4634 +-/* VEX bit flags */
4635 +-#define X86_VEX_W(vex) ((vex) & 0x80) /* VEX3 Byte2 */
4636 +-#define X86_VEX_R(vex) ((vex) & 0x80) /* VEX2/3 Byte1 */
4637 +-#define X86_VEX_X(vex) ((vex) & 0x40) /* VEX3 Byte1 */
4638 +-#define X86_VEX_B(vex) ((vex) & 0x20) /* VEX3 Byte1 */
4639 +-#define X86_VEX_L(vex) ((vex) & 0x04) /* VEX3 Byte2, VEX2 Byte1 */
4640 +-/* VEX bit fields */
4641 +-#define X86_EVEX_M(vex) ((vex) & 0x03) /* EVEX Byte1 */
4642 +-#define X86_VEX3_M(vex) ((vex) & 0x1f) /* VEX3 Byte1 */
4643 +-#define X86_VEX2_M 1 /* VEX2.M always 1 */
4644 +-#define X86_VEX_V(vex) (((vex) & 0x78) >> 3) /* VEX3 Byte2, VEX2 Byte1 */
4645 +-#define X86_VEX_P(vex) ((vex) & 0x03) /* VEX3 Byte2, VEX2 Byte1 */
4646 +-#define X86_VEX_M_MAX 0x1f /* VEX3.M Maximum value */
4647 +-
4648 +-extern void insn_init(struct insn *insn, const void *kaddr, int buf_len, int x86_64);
4649 +-extern void insn_get_prefixes(struct insn *insn);
4650 +-extern void insn_get_opcode(struct insn *insn);
4651 +-extern void insn_get_modrm(struct insn *insn);
4652 +-extern void insn_get_sib(struct insn *insn);
4653 +-extern void insn_get_displacement(struct insn *insn);
4654 +-extern void insn_get_immediate(struct insn *insn);
4655 +-extern void insn_get_length(struct insn *insn);
4656 +-
4657 +-/* Attribute will be determined after getting ModRM (for opcode groups) */
4658 +-static inline void insn_get_attribute(struct insn *insn)
4659 +-{
4660 +- insn_get_modrm(insn);
4661 +-}
4662 +-
4663 +-/* Instruction uses RIP-relative addressing */
4664 +-extern int insn_rip_relative(struct insn *insn);
4665 +-
4666 +-/* Init insn for kernel text */
4667 +-static inline void kernel_insn_init(struct insn *insn,
4668 +- const void *kaddr, int buf_len)
4669 +-{
4670 +-#ifdef CONFIG_X86_64
4671 +- insn_init(insn, kaddr, buf_len, 1);
4672 +-#else /* CONFIG_X86_32 */
4673 +- insn_init(insn, kaddr, buf_len, 0);
4674 +-#endif
4675 +-}
4676 +-
4677 +-static inline int insn_is_avx(struct insn *insn)
4678 +-{
4679 +- if (!insn->prefixes.got)
4680 +- insn_get_prefixes(insn);
4681 +- return (insn->vex_prefix.value != 0);
4682 +-}
4683 +-
4684 +-static inline int insn_is_evex(struct insn *insn)
4685 +-{
4686 +- if (!insn->prefixes.got)
4687 +- insn_get_prefixes(insn);
4688 +- return (insn->vex_prefix.nbytes == 4);
4689 +-}
4690 +-
4691 +-/* Ensure this instruction is decoded completely */
4692 +-static inline int insn_complete(struct insn *insn)
4693 +-{
4694 +- return insn->opcode.got && insn->modrm.got && insn->sib.got &&
4695 +- insn->displacement.got && insn->immediate.got;
4696 +-}
4697 +-
4698 +-static inline insn_byte_t insn_vex_m_bits(struct insn *insn)
4699 +-{
4700 +- if (insn->vex_prefix.nbytes == 2) /* 2 bytes VEX */
4701 +- return X86_VEX2_M;
4702 +- else if (insn->vex_prefix.nbytes == 3) /* 3 bytes VEX */
4703 +- return X86_VEX3_M(insn->vex_prefix.bytes[1]);
4704 +- else /* EVEX */
4705 +- return X86_EVEX_M(insn->vex_prefix.bytes[1]);
4706 +-}
4707 +-
4708 +-static inline insn_byte_t insn_vex_p_bits(struct insn *insn)
4709 +-{
4710 +- if (insn->vex_prefix.nbytes == 2) /* 2 bytes VEX */
4711 +- return X86_VEX_P(insn->vex_prefix.bytes[1]);
4712 +- else
4713 +- return X86_VEX_P(insn->vex_prefix.bytes[2]);
4714 +-}
4715 +-
4716 +-/* Get the last prefix id from last prefix or VEX prefix */
4717 +-static inline int insn_last_prefix_id(struct insn *insn)
4718 +-{
4719 +- if (insn_is_avx(insn))
4720 +- return insn_vex_p_bits(insn); /* VEX_p is a SIMD prefix id */
4721 +-
4722 +- if (insn->prefixes.bytes[3])
4723 +- return inat_get_last_prefix_id(insn->prefixes.bytes[3]);
4724 +-
4725 +- return 0;
4726 +-}
4727 +-
4728 +-/* Offset of each field from kaddr */
4729 +-static inline int insn_offset_rex_prefix(struct insn *insn)
4730 +-{
4731 +- return insn->prefixes.nbytes;
4732 +-}
4733 +-static inline int insn_offset_vex_prefix(struct insn *insn)
4734 +-{
4735 +- return insn_offset_rex_prefix(insn) + insn->rex_prefix.nbytes;
4736 +-}
4737 +-static inline int insn_offset_opcode(struct insn *insn)
4738 +-{
4739 +- return insn_offset_vex_prefix(insn) + insn->vex_prefix.nbytes;
4740 +-}
4741 +-static inline int insn_offset_modrm(struct insn *insn)
4742 +-{
4743 +- return insn_offset_opcode(insn) + insn->opcode.nbytes;
4744 +-}
4745 +-static inline int insn_offset_sib(struct insn *insn)
4746 +-{
4747 +- return insn_offset_modrm(insn) + insn->modrm.nbytes;
4748 +-}
4749 +-static inline int insn_offset_displacement(struct insn *insn)
4750 +-{
4751 +- return insn_offset_sib(insn) + insn->sib.nbytes;
4752 +-}
4753 +-static inline int insn_offset_immediate(struct insn *insn)
4754 +-{
4755 +- return insn_offset_displacement(insn) + insn->displacement.nbytes;
4756 +-}
4757 +-
4758 +-#endif /* _ASM_X86_INSN_H */
4759 +diff --git a/tools/objtool/arch/x86/insn/x86-opcode-map.txt b/tools/objtool/arch/x86/insn/x86-opcode-map.txt
4760 +deleted file mode 100644
4761 +index 1754e094bc28..000000000000
4762 +--- a/tools/objtool/arch/x86/insn/x86-opcode-map.txt
4763 ++++ /dev/null
4764 +@@ -1,1063 +0,0 @@
4765 +-# x86 Opcode Maps
4766 +-#
4767 +-# This is (mostly) based on following documentations.
4768 +-# - Intel(R) 64 and IA-32 Architectures Software Developer's Manual Vol.2C
4769 +-# (#326018-047US, June 2013)
4770 +-#
4771 +-#<Opcode maps>
4772 +-# Table: table-name
4773 +-# Referrer: escaped-name
4774 +-# AVXcode: avx-code
4775 +-# opcode: mnemonic|GrpXXX [operand1[,operand2...]] [(extra1)[,(extra2)...] [| 2nd-mnemonic ...]
4776 +-# (or)
4777 +-# opcode: escape # escaped-name
4778 +-# EndTable
4779 +-#
4780 +-# mnemonics that begin with lowercase 'v' accept a VEX or EVEX prefix
4781 +-# mnemonics that begin with lowercase 'k' accept a VEX prefix
4782 +-#
4783 +-#<group maps>
4784 +-# GrpTable: GrpXXX
4785 +-# reg: mnemonic [operand1[,operand2...]] [(extra1)[,(extra2)...] [| 2nd-mnemonic ...]
4786 +-# EndTable
4787 +-#
4788 +-# AVX Superscripts
4789 +-# (ev): this opcode requires EVEX prefix.
4790 +-# (evo): this opcode is changed by EVEX prefix (EVEX opcode)
4791 +-# (v): this opcode requires VEX prefix.
4792 +-# (v1): this opcode only supports 128bit VEX.
4793 +-#
4794 +-# Last Prefix Superscripts
4795 +-# - (66): the last prefix is 0x66
4796 +-# - (F3): the last prefix is 0xF3
4797 +-# - (F2): the last prefix is 0xF2
4798 +-# - (!F3) : the last prefix is not 0xF3 (including non-last prefix case)
4799 +-# - (66&F2): Both 0x66 and 0xF2 prefixes are specified.
4800 +-
4801 +-Table: one byte opcode
4802 +-Referrer:
4803 +-AVXcode:
4804 +-# 0x00 - 0x0f
4805 +-00: ADD Eb,Gb
4806 +-01: ADD Ev,Gv
4807 +-02: ADD Gb,Eb
4808 +-03: ADD Gv,Ev
4809 +-04: ADD AL,Ib
4810 +-05: ADD rAX,Iz
4811 +-06: PUSH ES (i64)
4812 +-07: POP ES (i64)
4813 +-08: OR Eb,Gb
4814 +-09: OR Ev,Gv
4815 +-0a: OR Gb,Eb
4816 +-0b: OR Gv,Ev
4817 +-0c: OR AL,Ib
4818 +-0d: OR rAX,Iz
4819 +-0e: PUSH CS (i64)
4820 +-0f: escape # 2-byte escape
4821 +-# 0x10 - 0x1f
4822 +-10: ADC Eb,Gb
4823 +-11: ADC Ev,Gv
4824 +-12: ADC Gb,Eb
4825 +-13: ADC Gv,Ev
4826 +-14: ADC AL,Ib
4827 +-15: ADC rAX,Iz
4828 +-16: PUSH SS (i64)
4829 +-17: POP SS (i64)
4830 +-18: SBB Eb,Gb
4831 +-19: SBB Ev,Gv
4832 +-1a: SBB Gb,Eb
4833 +-1b: SBB Gv,Ev
4834 +-1c: SBB AL,Ib
4835 +-1d: SBB rAX,Iz
4836 +-1e: PUSH DS (i64)
4837 +-1f: POP DS (i64)
4838 +-# 0x20 - 0x2f
4839 +-20: AND Eb,Gb
4840 +-21: AND Ev,Gv
4841 +-22: AND Gb,Eb
4842 +-23: AND Gv,Ev
4843 +-24: AND AL,Ib
4844 +-25: AND rAx,Iz
4845 +-26: SEG=ES (Prefix)
4846 +-27: DAA (i64)
4847 +-28: SUB Eb,Gb
4848 +-29: SUB Ev,Gv
4849 +-2a: SUB Gb,Eb
4850 +-2b: SUB Gv,Ev
4851 +-2c: SUB AL,Ib
4852 +-2d: SUB rAX,Iz
4853 +-2e: SEG=CS (Prefix)
4854 +-2f: DAS (i64)
4855 +-# 0x30 - 0x3f
4856 +-30: XOR Eb,Gb
4857 +-31: XOR Ev,Gv
4858 +-32: XOR Gb,Eb
4859 +-33: XOR Gv,Ev
4860 +-34: XOR AL,Ib
4861 +-35: XOR rAX,Iz
4862 +-36: SEG=SS (Prefix)
4863 +-37: AAA (i64)
4864 +-38: CMP Eb,Gb
4865 +-39: CMP Ev,Gv
4866 +-3a: CMP Gb,Eb
4867 +-3b: CMP Gv,Ev
4868 +-3c: CMP AL,Ib
4869 +-3d: CMP rAX,Iz
4870 +-3e: SEG=DS (Prefix)
4871 +-3f: AAS (i64)
4872 +-# 0x40 - 0x4f
4873 +-40: INC eAX (i64) | REX (o64)
4874 +-41: INC eCX (i64) | REX.B (o64)
4875 +-42: INC eDX (i64) | REX.X (o64)
4876 +-43: INC eBX (i64) | REX.XB (o64)
4877 +-44: INC eSP (i64) | REX.R (o64)
4878 +-45: INC eBP (i64) | REX.RB (o64)
4879 +-46: INC eSI (i64) | REX.RX (o64)
4880 +-47: INC eDI (i64) | REX.RXB (o64)
4881 +-48: DEC eAX (i64) | REX.W (o64)
4882 +-49: DEC eCX (i64) | REX.WB (o64)
4883 +-4a: DEC eDX (i64) | REX.WX (o64)
4884 +-4b: DEC eBX (i64) | REX.WXB (o64)
4885 +-4c: DEC eSP (i64) | REX.WR (o64)
4886 +-4d: DEC eBP (i64) | REX.WRB (o64)
4887 +-4e: DEC eSI (i64) | REX.WRX (o64)
4888 +-4f: DEC eDI (i64) | REX.WRXB (o64)
4889 +-# 0x50 - 0x5f
4890 +-50: PUSH rAX/r8 (d64)
4891 +-51: PUSH rCX/r9 (d64)
4892 +-52: PUSH rDX/r10 (d64)
4893 +-53: PUSH rBX/r11 (d64)
4894 +-54: PUSH rSP/r12 (d64)
4895 +-55: PUSH rBP/r13 (d64)
4896 +-56: PUSH rSI/r14 (d64)
4897 +-57: PUSH rDI/r15 (d64)
4898 +-58: POP rAX/r8 (d64)
4899 +-59: POP rCX/r9 (d64)
4900 +-5a: POP rDX/r10 (d64)
4901 +-5b: POP rBX/r11 (d64)
4902 +-5c: POP rSP/r12 (d64)
4903 +-5d: POP rBP/r13 (d64)
4904 +-5e: POP rSI/r14 (d64)
4905 +-5f: POP rDI/r15 (d64)
4906 +-# 0x60 - 0x6f
4907 +-60: PUSHA/PUSHAD (i64)
4908 +-61: POPA/POPAD (i64)
4909 +-62: BOUND Gv,Ma (i64) | EVEX (Prefix)
4910 +-63: ARPL Ew,Gw (i64) | MOVSXD Gv,Ev (o64)
4911 +-64: SEG=FS (Prefix)
4912 +-65: SEG=GS (Prefix)
4913 +-66: Operand-Size (Prefix)
4914 +-67: Address-Size (Prefix)
4915 +-68: PUSH Iz (d64)
4916 +-69: IMUL Gv,Ev,Iz
4917 +-6a: PUSH Ib (d64)
4918 +-6b: IMUL Gv,Ev,Ib
4919 +-6c: INS/INSB Yb,DX
4920 +-6d: INS/INSW/INSD Yz,DX
4921 +-6e: OUTS/OUTSB DX,Xb
4922 +-6f: OUTS/OUTSW/OUTSD DX,Xz
4923 +-# 0x70 - 0x7f
4924 +-70: JO Jb
4925 +-71: JNO Jb
4926 +-72: JB/JNAE/JC Jb
4927 +-73: JNB/JAE/JNC Jb
4928 +-74: JZ/JE Jb
4929 +-75: JNZ/JNE Jb
4930 +-76: JBE/JNA Jb
4931 +-77: JNBE/JA Jb
4932 +-78: JS Jb
4933 +-79: JNS Jb
4934 +-7a: JP/JPE Jb
4935 +-7b: JNP/JPO Jb
4936 +-7c: JL/JNGE Jb
4937 +-7d: JNL/JGE Jb
4938 +-7e: JLE/JNG Jb
4939 +-7f: JNLE/JG Jb
4940 +-# 0x80 - 0x8f
4941 +-80: Grp1 Eb,Ib (1A)
4942 +-81: Grp1 Ev,Iz (1A)
4943 +-82: Grp1 Eb,Ib (1A),(i64)
4944 +-83: Grp1 Ev,Ib (1A)
4945 +-84: TEST Eb,Gb
4946 +-85: TEST Ev,Gv
4947 +-86: XCHG Eb,Gb
4948 +-87: XCHG Ev,Gv
4949 +-88: MOV Eb,Gb
4950 +-89: MOV Ev,Gv
4951 +-8a: MOV Gb,Eb
4952 +-8b: MOV Gv,Ev
4953 +-8c: MOV Ev,Sw
4954 +-8d: LEA Gv,M
4955 +-8e: MOV Sw,Ew
4956 +-8f: Grp1A (1A) | POP Ev (d64)
4957 +-# 0x90 - 0x9f
4958 +-90: NOP | PAUSE (F3) | XCHG r8,rAX
4959 +-91: XCHG rCX/r9,rAX
4960 +-92: XCHG rDX/r10,rAX
4961 +-93: XCHG rBX/r11,rAX
4962 +-94: XCHG rSP/r12,rAX
4963 +-95: XCHG rBP/r13,rAX
4964 +-96: XCHG rSI/r14,rAX
4965 +-97: XCHG rDI/r15,rAX
4966 +-98: CBW/CWDE/CDQE
4967 +-99: CWD/CDQ/CQO
4968 +-9a: CALLF Ap (i64)
4969 +-9b: FWAIT/WAIT
4970 +-9c: PUSHF/D/Q Fv (d64)
4971 +-9d: POPF/D/Q Fv (d64)
4972 +-9e: SAHF
4973 +-9f: LAHF
4974 +-# 0xa0 - 0xaf
4975 +-a0: MOV AL,Ob
4976 +-a1: MOV rAX,Ov
4977 +-a2: MOV Ob,AL
4978 +-a3: MOV Ov,rAX
4979 +-a4: MOVS/B Yb,Xb
4980 +-a5: MOVS/W/D/Q Yv,Xv
4981 +-a6: CMPS/B Xb,Yb
4982 +-a7: CMPS/W/D Xv,Yv
4983 +-a8: TEST AL,Ib
4984 +-a9: TEST rAX,Iz
4985 +-aa: STOS/B Yb,AL
4986 +-ab: STOS/W/D/Q Yv,rAX
4987 +-ac: LODS/B AL,Xb
4988 +-ad: LODS/W/D/Q rAX,Xv
4989 +-ae: SCAS/B AL,Yb
4990 +-# Note: The May 2011 Intel manual shows Xv for the second parameter of the
4991 +-# next instruction but Yv is correct
4992 +-af: SCAS/W/D/Q rAX,Yv
4993 +-# 0xb0 - 0xbf
4994 +-b0: MOV AL/R8L,Ib
4995 +-b1: MOV CL/R9L,Ib
4996 +-b2: MOV DL/R10L,Ib
4997 +-b3: MOV BL/R11L,Ib
4998 +-b4: MOV AH/R12L,Ib
4999 +-b5: MOV CH/R13L,Ib
5000 +-b6: MOV DH/R14L,Ib
5001 +-b7: MOV BH/R15L,Ib
5002 +-b8: MOV rAX/r8,Iv
5003 +-b9: MOV rCX/r9,Iv
5004 +-ba: MOV rDX/r10,Iv
5005 +-bb: MOV rBX/r11,Iv
5006 +-bc: MOV rSP/r12,Iv
5007 +-bd: MOV rBP/r13,Iv
5008 +-be: MOV rSI/r14,Iv
5009 +-bf: MOV rDI/r15,Iv
5010 +-# 0xc0 - 0xcf
5011 +-c0: Grp2 Eb,Ib (1A)
5012 +-c1: Grp2 Ev,Ib (1A)
5013 +-c2: RETN Iw (f64)
5014 +-c3: RETN
5015 +-c4: LES Gz,Mp (i64) | VEX+2byte (Prefix)
5016 +-c5: LDS Gz,Mp (i64) | VEX+1byte (Prefix)
5017 +-c6: Grp11A Eb,Ib (1A)
5018 +-c7: Grp11B Ev,Iz (1A)
5019 +-c8: ENTER Iw,Ib
5020 +-c9: LEAVE (d64)
5021 +-ca: RETF Iw
5022 +-cb: RETF
5023 +-cc: INT3
5024 +-cd: INT Ib
5025 +-ce: INTO (i64)
5026 +-cf: IRET/D/Q
5027 +-# 0xd0 - 0xdf
5028 +-d0: Grp2 Eb,1 (1A)
5029 +-d1: Grp2 Ev,1 (1A)
5030 +-d2: Grp2 Eb,CL (1A)
5031 +-d3: Grp2 Ev,CL (1A)
5032 +-d4: AAM Ib (i64)
5033 +-d5: AAD Ib (i64)
5034 +-d6:
5035 +-d7: XLAT/XLATB
5036 +-d8: ESC
5037 +-d9: ESC
5038 +-da: ESC
5039 +-db: ESC
5040 +-dc: ESC
5041 +-dd: ESC
5042 +-de: ESC
5043 +-df: ESC
5044 +-# 0xe0 - 0xef
5045 +-# Note: "forced64" is Intel CPU behavior: they ignore 0x66 prefix
5046 +-# in 64-bit mode. AMD CPUs accept 0x66 prefix, it causes RIP truncation
5047 +-# to 16 bits. In 32-bit mode, 0x66 is accepted by both Intel and AMD.
5048 +-e0: LOOPNE/LOOPNZ Jb (f64)
5049 +-e1: LOOPE/LOOPZ Jb (f64)
5050 +-e2: LOOP Jb (f64)
5051 +-e3: JrCXZ Jb (f64)
5052 +-e4: IN AL,Ib
5053 +-e5: IN eAX,Ib
5054 +-e6: OUT Ib,AL
5055 +-e7: OUT Ib,eAX
5056 +-# With 0x66 prefix in 64-bit mode, for AMD CPUs immediate offset
5057 +-# in "near" jumps and calls is 16-bit. For CALL,
5058 +-# push of return address is 16-bit wide, RSP is decremented by 2
5059 +-# but is not truncated to 16 bits, unlike RIP.
5060 +-e8: CALL Jz (f64)
5061 +-e9: JMP-near Jz (f64)
5062 +-ea: JMP-far Ap (i64)
5063 +-eb: JMP-short Jb (f64)
5064 +-ec: IN AL,DX
5065 +-ed: IN eAX,DX
5066 +-ee: OUT DX,AL
5067 +-ef: OUT DX,eAX
5068 +-# 0xf0 - 0xff
5069 +-f0: LOCK (Prefix)
5070 +-f1:
5071 +-f2: REPNE (Prefix) | XACQUIRE (Prefix)
5072 +-f3: REP/REPE (Prefix) | XRELEASE (Prefix)
5073 +-f4: HLT
5074 +-f5: CMC
5075 +-f6: Grp3_1 Eb (1A)
5076 +-f7: Grp3_2 Ev (1A)
5077 +-f8: CLC
5078 +-f9: STC
5079 +-fa: CLI
5080 +-fb: STI
5081 +-fc: CLD
5082 +-fd: STD
5083 +-fe: Grp4 (1A)
5084 +-ff: Grp5 (1A)
5085 +-EndTable
5086 +-
5087 +-Table: 2-byte opcode (0x0f)
5088 +-Referrer: 2-byte escape
5089 +-AVXcode: 1
5090 +-# 0x0f 0x00-0x0f
5091 +-00: Grp6 (1A)
5092 +-01: Grp7 (1A)
5093 +-02: LAR Gv,Ew
5094 +-03: LSL Gv,Ew
5095 +-04:
5096 +-05: SYSCALL (o64)
5097 +-06: CLTS
5098 +-07: SYSRET (o64)
5099 +-08: INVD
5100 +-09: WBINVD
5101 +-0a:
5102 +-0b: UD2 (1B)
5103 +-0c:
5104 +-# AMD's prefetch group. Intel supports prefetchw(/1) only.
5105 +-0d: GrpP
5106 +-0e: FEMMS
5107 +-# 3DNow! uses the last imm byte as opcode extension.
5108 +-0f: 3DNow! Pq,Qq,Ib
5109 +-# 0x0f 0x10-0x1f
5110 +-# NOTE: According to Intel SDM opcode map, vmovups and vmovupd has no operands
5111 +-# but it actually has operands. And also, vmovss and vmovsd only accept 128bit.
5112 +-# MOVSS/MOVSD has too many forms(3) on SDM. This map just shows a typical form.
5113 +-# Many AVX instructions lack v1 superscript, according to Intel AVX-Prgramming
5114 +-# Reference A.1
5115 +-10: vmovups Vps,Wps | vmovupd Vpd,Wpd (66) | vmovss Vx,Hx,Wss (F3),(v1) | vmovsd Vx,Hx,Wsd (F2),(v1)
5116 +-11: vmovups Wps,Vps | vmovupd Wpd,Vpd (66) | vmovss Wss,Hx,Vss (F3),(v1) | vmovsd Wsd,Hx,Vsd (F2),(v1)
5117 +-12: vmovlps Vq,Hq,Mq (v1) | vmovhlps Vq,Hq,Uq (v1) | vmovlpd Vq,Hq,Mq (66),(v1) | vmovsldup Vx,Wx (F3) | vmovddup Vx,Wx (F2)
5118 +-13: vmovlps Mq,Vq (v1) | vmovlpd Mq,Vq (66),(v1)
5119 +-14: vunpcklps Vx,Hx,Wx | vunpcklpd Vx,Hx,Wx (66)
5120 +-15: vunpckhps Vx,Hx,Wx | vunpckhpd Vx,Hx,Wx (66)
5121 +-16: vmovhps Vdq,Hq,Mq (v1) | vmovlhps Vdq,Hq,Uq (v1) | vmovhpd Vdq,Hq,Mq (66),(v1) | vmovshdup Vx,Wx (F3)
5122 +-17: vmovhps Mq,Vq (v1) | vmovhpd Mq,Vq (66),(v1)
5123 +-18: Grp16 (1A)
5124 +-19:
5125 +-# Intel SDM opcode map does not list MPX instructions. For now using Gv for
5126 +-# bnd registers and Ev for everything else is OK because the instruction
5127 +-# decoder does not use the information except as an indication that there is
5128 +-# a ModR/M byte.
5129 +-1a: BNDCL Gv,Ev (F3) | BNDCU Gv,Ev (F2) | BNDMOV Gv,Ev (66) | BNDLDX Gv,Ev
5130 +-1b: BNDCN Gv,Ev (F2) | BNDMOV Ev,Gv (66) | BNDMK Gv,Ev (F3) | BNDSTX Ev,Gv
5131 +-1c:
5132 +-1d:
5133 +-1e:
5134 +-1f: NOP Ev
5135 +-# 0x0f 0x20-0x2f
5136 +-20: MOV Rd,Cd
5137 +-21: MOV Rd,Dd
5138 +-22: MOV Cd,Rd
5139 +-23: MOV Dd,Rd
5140 +-24:
5141 +-25:
5142 +-26:
5143 +-27:
5144 +-28: vmovaps Vps,Wps | vmovapd Vpd,Wpd (66)
5145 +-29: vmovaps Wps,Vps | vmovapd Wpd,Vpd (66)
5146 +-2a: cvtpi2ps Vps,Qpi | cvtpi2pd Vpd,Qpi (66) | vcvtsi2ss Vss,Hss,Ey (F3),(v1) | vcvtsi2sd Vsd,Hsd,Ey (F2),(v1)
5147 +-2b: vmovntps Mps,Vps | vmovntpd Mpd,Vpd (66)
5148 +-2c: cvttps2pi Ppi,Wps | cvttpd2pi Ppi,Wpd (66) | vcvttss2si Gy,Wss (F3),(v1) | vcvttsd2si Gy,Wsd (F2),(v1)
5149 +-2d: cvtps2pi Ppi,Wps | cvtpd2pi Qpi,Wpd (66) | vcvtss2si Gy,Wss (F3),(v1) | vcvtsd2si Gy,Wsd (F2),(v1)
5150 +-2e: vucomiss Vss,Wss (v1) | vucomisd Vsd,Wsd (66),(v1)
5151 +-2f: vcomiss Vss,Wss (v1) | vcomisd Vsd,Wsd (66),(v1)
5152 +-# 0x0f 0x30-0x3f
5153 +-30: WRMSR
5154 +-31: RDTSC
5155 +-32: RDMSR
5156 +-33: RDPMC
5157 +-34: SYSENTER
5158 +-35: SYSEXIT
5159 +-36:
5160 +-37: GETSEC
5161 +-38: escape # 3-byte escape 1
5162 +-39:
5163 +-3a: escape # 3-byte escape 2
5164 +-3b:
5165 +-3c:
5166 +-3d:
5167 +-3e:
5168 +-3f:
5169 +-# 0x0f 0x40-0x4f
5170 +-40: CMOVO Gv,Ev
5171 +-41: CMOVNO Gv,Ev | kandw/q Vk,Hk,Uk | kandb/d Vk,Hk,Uk (66)
5172 +-42: CMOVB/C/NAE Gv,Ev | kandnw/q Vk,Hk,Uk | kandnb/d Vk,Hk,Uk (66)
5173 +-43: CMOVAE/NB/NC Gv,Ev
5174 +-44: CMOVE/Z Gv,Ev | knotw/q Vk,Uk | knotb/d Vk,Uk (66)
5175 +-45: CMOVNE/NZ Gv,Ev | korw/q Vk,Hk,Uk | korb/d Vk,Hk,Uk (66)
5176 +-46: CMOVBE/NA Gv,Ev | kxnorw/q Vk,Hk,Uk | kxnorb/d Vk,Hk,Uk (66)
5177 +-47: CMOVA/NBE Gv,Ev | kxorw/q Vk,Hk,Uk | kxorb/d Vk,Hk,Uk (66)
5178 +-48: CMOVS Gv,Ev
5179 +-49: CMOVNS Gv,Ev
5180 +-4a: CMOVP/PE Gv,Ev | kaddw/q Vk,Hk,Uk | kaddb/d Vk,Hk,Uk (66)
5181 +-4b: CMOVNP/PO Gv,Ev | kunpckbw Vk,Hk,Uk (66) | kunpckwd/dq Vk,Hk,Uk
5182 +-4c: CMOVL/NGE Gv,Ev
5183 +-4d: CMOVNL/GE Gv,Ev
5184 +-4e: CMOVLE/NG Gv,Ev
5185 +-4f: CMOVNLE/G Gv,Ev
5186 +-# 0x0f 0x50-0x5f
5187 +-50: vmovmskps Gy,Ups | vmovmskpd Gy,Upd (66)
5188 +-51: vsqrtps Vps,Wps | vsqrtpd Vpd,Wpd (66) | vsqrtss Vss,Hss,Wss (F3),(v1) | vsqrtsd Vsd,Hsd,Wsd (F2),(v1)
5189 +-52: vrsqrtps Vps,Wps | vrsqrtss Vss,Hss,Wss (F3),(v1)
5190 +-53: vrcpps Vps,Wps | vrcpss Vss,Hss,Wss (F3),(v1)
5191 +-54: vandps Vps,Hps,Wps | vandpd Vpd,Hpd,Wpd (66)
5192 +-55: vandnps Vps,Hps,Wps | vandnpd Vpd,Hpd,Wpd (66)
5193 +-56: vorps Vps,Hps,Wps | vorpd Vpd,Hpd,Wpd (66)
5194 +-57: vxorps Vps,Hps,Wps | vxorpd Vpd,Hpd,Wpd (66)
5195 +-58: vaddps Vps,Hps,Wps | vaddpd Vpd,Hpd,Wpd (66) | vaddss Vss,Hss,Wss (F3),(v1) | vaddsd Vsd,Hsd,Wsd (F2),(v1)
5196 +-59: vmulps Vps,Hps,Wps | vmulpd Vpd,Hpd,Wpd (66) | vmulss Vss,Hss,Wss (F3),(v1) | vmulsd Vsd,Hsd,Wsd (F2),(v1)
5197 +-5a: vcvtps2pd Vpd,Wps | vcvtpd2ps Vps,Wpd (66) | vcvtss2sd Vsd,Hx,Wss (F3),(v1) | vcvtsd2ss Vss,Hx,Wsd (F2),(v1)
5198 +-5b: vcvtdq2ps Vps,Wdq | vcvtqq2ps Vps,Wqq (evo) | vcvtps2dq Vdq,Wps (66) | vcvttps2dq Vdq,Wps (F3)
5199 +-5c: vsubps Vps,Hps,Wps | vsubpd Vpd,Hpd,Wpd (66) | vsubss Vss,Hss,Wss (F3),(v1) | vsubsd Vsd,Hsd,Wsd (F2),(v1)
5200 +-5d: vminps Vps,Hps,Wps | vminpd Vpd,Hpd,Wpd (66) | vminss Vss,Hss,Wss (F3),(v1) | vminsd Vsd,Hsd,Wsd (F2),(v1)
5201 +-5e: vdivps Vps,Hps,Wps | vdivpd Vpd,Hpd,Wpd (66) | vdivss Vss,Hss,Wss (F3),(v1) | vdivsd Vsd,Hsd,Wsd (F2),(v1)
5202 +-5f: vmaxps Vps,Hps,Wps | vmaxpd Vpd,Hpd,Wpd (66) | vmaxss Vss,Hss,Wss (F3),(v1) | vmaxsd Vsd,Hsd,Wsd (F2),(v1)
5203 +-# 0x0f 0x60-0x6f
5204 +-60: punpcklbw Pq,Qd | vpunpcklbw Vx,Hx,Wx (66),(v1)
5205 +-61: punpcklwd Pq,Qd | vpunpcklwd Vx,Hx,Wx (66),(v1)
5206 +-62: punpckldq Pq,Qd | vpunpckldq Vx,Hx,Wx (66),(v1)
5207 +-63: packsswb Pq,Qq | vpacksswb Vx,Hx,Wx (66),(v1)
5208 +-64: pcmpgtb Pq,Qq | vpcmpgtb Vx,Hx,Wx (66),(v1)
5209 +-65: pcmpgtw Pq,Qq | vpcmpgtw Vx,Hx,Wx (66),(v1)
5210 +-66: pcmpgtd Pq,Qq | vpcmpgtd Vx,Hx,Wx (66),(v1)
5211 +-67: packuswb Pq,Qq | vpackuswb Vx,Hx,Wx (66),(v1)
5212 +-68: punpckhbw Pq,Qd | vpunpckhbw Vx,Hx,Wx (66),(v1)
5213 +-69: punpckhwd Pq,Qd | vpunpckhwd Vx,Hx,Wx (66),(v1)
5214 +-6a: punpckhdq Pq,Qd | vpunpckhdq Vx,Hx,Wx (66),(v1)
5215 +-6b: packssdw Pq,Qd | vpackssdw Vx,Hx,Wx (66),(v1)
5216 +-6c: vpunpcklqdq Vx,Hx,Wx (66),(v1)
5217 +-6d: vpunpckhqdq Vx,Hx,Wx (66),(v1)
5218 +-6e: movd/q Pd,Ey | vmovd/q Vy,Ey (66),(v1)
5219 +-6f: movq Pq,Qq | vmovdqa Vx,Wx (66) | vmovdqa32/64 Vx,Wx (66),(evo) | vmovdqu Vx,Wx (F3) | vmovdqu32/64 Vx,Wx (F3),(evo) | vmovdqu8/16 Vx,Wx (F2),(ev)
5220 +-# 0x0f 0x70-0x7f
5221 +-70: pshufw Pq,Qq,Ib | vpshufd Vx,Wx,Ib (66),(v1) | vpshufhw Vx,Wx,Ib (F3),(v1) | vpshuflw Vx,Wx,Ib (F2),(v1)
5222 +-71: Grp12 (1A)
5223 +-72: Grp13 (1A)
5224 +-73: Grp14 (1A)
5225 +-74: pcmpeqb Pq,Qq | vpcmpeqb Vx,Hx,Wx (66),(v1)
5226 +-75: pcmpeqw Pq,Qq | vpcmpeqw Vx,Hx,Wx (66),(v1)
5227 +-76: pcmpeqd Pq,Qq | vpcmpeqd Vx,Hx,Wx (66),(v1)
5228 +-# Note: Remove (v), because vzeroall and vzeroupper becomes emms without VEX.
5229 +-77: emms | vzeroupper | vzeroall
5230 +-78: VMREAD Ey,Gy | vcvttps2udq/pd2udq Vx,Wpd (evo) | vcvttsd2usi Gv,Wx (F2),(ev) | vcvttss2usi Gv,Wx (F3),(ev) | vcvttps2uqq/pd2uqq Vx,Wx (66),(ev)
5231 +-79: VMWRITE Gy,Ey | vcvtps2udq/pd2udq Vx,Wpd (evo) | vcvtsd2usi Gv,Wx (F2),(ev) | vcvtss2usi Gv,Wx (F3),(ev) | vcvtps2uqq/pd2uqq Vx,Wx (66),(ev)
5232 +-7a: vcvtudq2pd/uqq2pd Vpd,Wx (F3),(ev) | vcvtudq2ps/uqq2ps Vpd,Wx (F2),(ev) | vcvttps2qq/pd2qq Vx,Wx (66),(ev)
5233 +-7b: vcvtusi2sd Vpd,Hpd,Ev (F2),(ev) | vcvtusi2ss Vps,Hps,Ev (F3),(ev) | vcvtps2qq/pd2qq Vx,Wx (66),(ev)
5234 +-7c: vhaddpd Vpd,Hpd,Wpd (66) | vhaddps Vps,Hps,Wps (F2)
5235 +-7d: vhsubpd Vpd,Hpd,Wpd (66) | vhsubps Vps,Hps,Wps (F2)
5236 +-7e: movd/q Ey,Pd | vmovd/q Ey,Vy (66),(v1) | vmovq Vq,Wq (F3),(v1)
5237 +-7f: movq Qq,Pq | vmovdqa Wx,Vx (66) | vmovdqa32/64 Wx,Vx (66),(evo) | vmovdqu Wx,Vx (F3) | vmovdqu32/64 Wx,Vx (F3),(evo) | vmovdqu8/16 Wx,Vx (F2),(ev)
5238 +-# 0x0f 0x80-0x8f
5239 +-# Note: "forced64" is Intel CPU behavior (see comment about CALL insn).
5240 +-80: JO Jz (f64)
5241 +-81: JNO Jz (f64)
5242 +-82: JB/JC/JNAE Jz (f64)
5243 +-83: JAE/JNB/JNC Jz (f64)
5244 +-84: JE/JZ Jz (f64)
5245 +-85: JNE/JNZ Jz (f64)
5246 +-86: JBE/JNA Jz (f64)
5247 +-87: JA/JNBE Jz (f64)
5248 +-88: JS Jz (f64)
5249 +-89: JNS Jz (f64)
5250 +-8a: JP/JPE Jz (f64)
5251 +-8b: JNP/JPO Jz (f64)
5252 +-8c: JL/JNGE Jz (f64)
5253 +-8d: JNL/JGE Jz (f64)
5254 +-8e: JLE/JNG Jz (f64)
5255 +-8f: JNLE/JG Jz (f64)
5256 +-# 0x0f 0x90-0x9f
5257 +-90: SETO Eb | kmovw/q Vk,Wk | kmovb/d Vk,Wk (66)
5258 +-91: SETNO Eb | kmovw/q Mv,Vk | kmovb/d Mv,Vk (66)
5259 +-92: SETB/C/NAE Eb | kmovw Vk,Rv | kmovb Vk,Rv (66) | kmovq/d Vk,Rv (F2)
5260 +-93: SETAE/NB/NC Eb | kmovw Gv,Uk | kmovb Gv,Uk (66) | kmovq/d Gv,Uk (F2)
5261 +-94: SETE/Z Eb
5262 +-95: SETNE/NZ Eb
5263 +-96: SETBE/NA Eb
5264 +-97: SETA/NBE Eb
5265 +-98: SETS Eb | kortestw/q Vk,Uk | kortestb/d Vk,Uk (66)
5266 +-99: SETNS Eb | ktestw/q Vk,Uk | ktestb/d Vk,Uk (66)
5267 +-9a: SETP/PE Eb
5268 +-9b: SETNP/PO Eb
5269 +-9c: SETL/NGE Eb
5270 +-9d: SETNL/GE Eb
5271 +-9e: SETLE/NG Eb
5272 +-9f: SETNLE/G Eb
5273 +-# 0x0f 0xa0-0xaf
5274 +-a0: PUSH FS (d64)
5275 +-a1: POP FS (d64)
5276 +-a2: CPUID
5277 +-a3: BT Ev,Gv
5278 +-a4: SHLD Ev,Gv,Ib
5279 +-a5: SHLD Ev,Gv,CL
5280 +-a6: GrpPDLK
5281 +-a7: GrpRNG
5282 +-a8: PUSH GS (d64)
5283 +-a9: POP GS (d64)
5284 +-aa: RSM
5285 +-ab: BTS Ev,Gv
5286 +-ac: SHRD Ev,Gv,Ib
5287 +-ad: SHRD Ev,Gv,CL
5288 +-ae: Grp15 (1A),(1C)
5289 +-af: IMUL Gv,Ev
5290 +-# 0x0f 0xb0-0xbf
5291 +-b0: CMPXCHG Eb,Gb
5292 +-b1: CMPXCHG Ev,Gv
5293 +-b2: LSS Gv,Mp
5294 +-b3: BTR Ev,Gv
5295 +-b4: LFS Gv,Mp
5296 +-b5: LGS Gv,Mp
5297 +-b6: MOVZX Gv,Eb
5298 +-b7: MOVZX Gv,Ew
5299 +-b8: JMPE (!F3) | POPCNT Gv,Ev (F3)
5300 +-b9: Grp10 (1A)
5301 +-ba: Grp8 Ev,Ib (1A)
5302 +-bb: BTC Ev,Gv
5303 +-bc: BSF Gv,Ev (!F3) | TZCNT Gv,Ev (F3)
5304 +-bd: BSR Gv,Ev (!F3) | LZCNT Gv,Ev (F3)
5305 +-be: MOVSX Gv,Eb
5306 +-bf: MOVSX Gv,Ew
5307 +-# 0x0f 0xc0-0xcf
5308 +-c0: XADD Eb,Gb
5309 +-c1: XADD Ev,Gv
5310 +-c2: vcmpps Vps,Hps,Wps,Ib | vcmppd Vpd,Hpd,Wpd,Ib (66) | vcmpss Vss,Hss,Wss,Ib (F3),(v1) | vcmpsd Vsd,Hsd,Wsd,Ib (F2),(v1)
5311 +-c3: movnti My,Gy
5312 +-c4: pinsrw Pq,Ry/Mw,Ib | vpinsrw Vdq,Hdq,Ry/Mw,Ib (66),(v1)
5313 +-c5: pextrw Gd,Nq,Ib | vpextrw Gd,Udq,Ib (66),(v1)
5314 +-c6: vshufps Vps,Hps,Wps,Ib | vshufpd Vpd,Hpd,Wpd,Ib (66)
5315 +-c7: Grp9 (1A)
5316 +-c8: BSWAP RAX/EAX/R8/R8D
5317 +-c9: BSWAP RCX/ECX/R9/R9D
5318 +-ca: BSWAP RDX/EDX/R10/R10D
5319 +-cb: BSWAP RBX/EBX/R11/R11D
5320 +-cc: BSWAP RSP/ESP/R12/R12D
5321 +-cd: BSWAP RBP/EBP/R13/R13D
5322 +-ce: BSWAP RSI/ESI/R14/R14D
5323 +-cf: BSWAP RDI/EDI/R15/R15D
5324 +-# 0x0f 0xd0-0xdf
5325 +-d0: vaddsubpd Vpd,Hpd,Wpd (66) | vaddsubps Vps,Hps,Wps (F2)
5326 +-d1: psrlw Pq,Qq | vpsrlw Vx,Hx,Wx (66),(v1)
5327 +-d2: psrld Pq,Qq | vpsrld Vx,Hx,Wx (66),(v1)
5328 +-d3: psrlq Pq,Qq | vpsrlq Vx,Hx,Wx (66),(v1)
5329 +-d4: paddq Pq,Qq | vpaddq Vx,Hx,Wx (66),(v1)
5330 +-d5: pmullw Pq,Qq | vpmullw Vx,Hx,Wx (66),(v1)
5331 +-d6: vmovq Wq,Vq (66),(v1) | movq2dq Vdq,Nq (F3) | movdq2q Pq,Uq (F2)
5332 +-d7: pmovmskb Gd,Nq | vpmovmskb Gd,Ux (66),(v1)
5333 +-d8: psubusb Pq,Qq | vpsubusb Vx,Hx,Wx (66),(v1)
5334 +-d9: psubusw Pq,Qq | vpsubusw Vx,Hx,Wx (66),(v1)
5335 +-da: pminub Pq,Qq | vpminub Vx,Hx,Wx (66),(v1)
5336 +-db: pand Pq,Qq | vpand Vx,Hx,Wx (66),(v1) | vpandd/q Vx,Hx,Wx (66),(evo)
5337 +-dc: paddusb Pq,Qq | vpaddusb Vx,Hx,Wx (66),(v1)
5338 +-dd: paddusw Pq,Qq | vpaddusw Vx,Hx,Wx (66),(v1)
5339 +-de: pmaxub Pq,Qq | vpmaxub Vx,Hx,Wx (66),(v1)
5340 +-df: pandn Pq,Qq | vpandn Vx,Hx,Wx (66),(v1) | vpandnd/q Vx,Hx,Wx (66),(evo)
5341 +-# 0x0f 0xe0-0xef
5342 +-e0: pavgb Pq,Qq | vpavgb Vx,Hx,Wx (66),(v1)
5343 +-e1: psraw Pq,Qq | vpsraw Vx,Hx,Wx (66),(v1)
5344 +-e2: psrad Pq,Qq | vpsrad Vx,Hx,Wx (66),(v1)
5345 +-e3: pavgw Pq,Qq | vpavgw Vx,Hx,Wx (66),(v1)
5346 +-e4: pmulhuw Pq,Qq | vpmulhuw Vx,Hx,Wx (66),(v1)
5347 +-e5: pmulhw Pq,Qq | vpmulhw Vx,Hx,Wx (66),(v1)
5348 +-e6: vcvttpd2dq Vx,Wpd (66) | vcvtdq2pd Vx,Wdq (F3) | vcvtdq2pd/qq2pd Vx,Wdq (F3),(evo) | vcvtpd2dq Vx,Wpd (F2)
5349 +-e7: movntq Mq,Pq | vmovntdq Mx,Vx (66)
5350 +-e8: psubsb Pq,Qq | vpsubsb Vx,Hx,Wx (66),(v1)
5351 +-e9: psubsw Pq,Qq | vpsubsw Vx,Hx,Wx (66),(v1)
5352 +-ea: pminsw Pq,Qq | vpminsw Vx,Hx,Wx (66),(v1)
5353 +-eb: por Pq,Qq | vpor Vx,Hx,Wx (66),(v1) | vpord/q Vx,Hx,Wx (66),(evo)
5354 +-ec: paddsb Pq,Qq | vpaddsb Vx,Hx,Wx (66),(v1)
5355 +-ed: paddsw Pq,Qq | vpaddsw Vx,Hx,Wx (66),(v1)
5356 +-ee: pmaxsw Pq,Qq | vpmaxsw Vx,Hx,Wx (66),(v1)
5357 +-ef: pxor Pq,Qq | vpxor Vx,Hx,Wx (66),(v1) | vpxord/q Vx,Hx,Wx (66),(evo)
5358 +-# 0x0f 0xf0-0xff
5359 +-f0: vlddqu Vx,Mx (F2)
5360 +-f1: psllw Pq,Qq | vpsllw Vx,Hx,Wx (66),(v1)
5361 +-f2: pslld Pq,Qq | vpslld Vx,Hx,Wx (66),(v1)
5362 +-f3: psllq Pq,Qq | vpsllq Vx,Hx,Wx (66),(v1)
5363 +-f4: pmuludq Pq,Qq | vpmuludq Vx,Hx,Wx (66),(v1)
5364 +-f5: pmaddwd Pq,Qq | vpmaddwd Vx,Hx,Wx (66),(v1)
5365 +-f6: psadbw Pq,Qq | vpsadbw Vx,Hx,Wx (66),(v1)
5366 +-f7: maskmovq Pq,Nq | vmaskmovdqu Vx,Ux (66),(v1)
5367 +-f8: psubb Pq,Qq | vpsubb Vx,Hx,Wx (66),(v1)
5368 +-f9: psubw Pq,Qq | vpsubw Vx,Hx,Wx (66),(v1)
5369 +-fa: psubd Pq,Qq | vpsubd Vx,Hx,Wx (66),(v1)
5370 +-fb: psubq Pq,Qq | vpsubq Vx,Hx,Wx (66),(v1)
5371 +-fc: paddb Pq,Qq | vpaddb Vx,Hx,Wx (66),(v1)
5372 +-fd: paddw Pq,Qq | vpaddw Vx,Hx,Wx (66),(v1)
5373 +-fe: paddd Pq,Qq | vpaddd Vx,Hx,Wx (66),(v1)
5374 +-ff:
5375 +-EndTable
5376 +-
5377 +-Table: 3-byte opcode 1 (0x0f 0x38)
5378 +-Referrer: 3-byte escape 1
5379 +-AVXcode: 2
5380 +-# 0x0f 0x38 0x00-0x0f
5381 +-00: pshufb Pq,Qq | vpshufb Vx,Hx,Wx (66),(v1)
5382 +-01: phaddw Pq,Qq | vphaddw Vx,Hx,Wx (66),(v1)
5383 +-02: phaddd Pq,Qq | vphaddd Vx,Hx,Wx (66),(v1)
5384 +-03: phaddsw Pq,Qq | vphaddsw Vx,Hx,Wx (66),(v1)
5385 +-04: pmaddubsw Pq,Qq | vpmaddubsw Vx,Hx,Wx (66),(v1)
5386 +-05: phsubw Pq,Qq | vphsubw Vx,Hx,Wx (66),(v1)
5387 +-06: phsubd Pq,Qq | vphsubd Vx,Hx,Wx (66),(v1)
5388 +-07: phsubsw Pq,Qq | vphsubsw Vx,Hx,Wx (66),(v1)
5389 +-08: psignb Pq,Qq | vpsignb Vx,Hx,Wx (66),(v1)
5390 +-09: psignw Pq,Qq | vpsignw Vx,Hx,Wx (66),(v1)
5391 +-0a: psignd Pq,Qq | vpsignd Vx,Hx,Wx (66),(v1)
5392 +-0b: pmulhrsw Pq,Qq | vpmulhrsw Vx,Hx,Wx (66),(v1)
5393 +-0c: vpermilps Vx,Hx,Wx (66),(v)
5394 +-0d: vpermilpd Vx,Hx,Wx (66),(v)
5395 +-0e: vtestps Vx,Wx (66),(v)
5396 +-0f: vtestpd Vx,Wx (66),(v)
5397 +-# 0x0f 0x38 0x10-0x1f
5398 +-10: pblendvb Vdq,Wdq (66) | vpsrlvw Vx,Hx,Wx (66),(evo) | vpmovuswb Wx,Vx (F3),(ev)
5399 +-11: vpmovusdb Wx,Vd (F3),(ev) | vpsravw Vx,Hx,Wx (66),(ev)
5400 +-12: vpmovusqb Wx,Vq (F3),(ev) | vpsllvw Vx,Hx,Wx (66),(ev)
5401 +-13: vcvtph2ps Vx,Wx (66),(v) | vpmovusdw Wx,Vd (F3),(ev)
5402 +-14: blendvps Vdq,Wdq (66) | vpmovusqw Wx,Vq (F3),(ev) | vprorvd/q Vx,Hx,Wx (66),(evo)
5403 +-15: blendvpd Vdq,Wdq (66) | vpmovusqd Wx,Vq (F3),(ev) | vprolvd/q Vx,Hx,Wx (66),(evo)
5404 +-16: vpermps Vqq,Hqq,Wqq (66),(v) | vpermps/d Vqq,Hqq,Wqq (66),(evo)
5405 +-17: vptest Vx,Wx (66)
5406 +-18: vbroadcastss Vx,Wd (66),(v)
5407 +-19: vbroadcastsd Vqq,Wq (66),(v) | vbroadcastf32x2 Vqq,Wq (66),(evo)
5408 +-1a: vbroadcastf128 Vqq,Mdq (66),(v) | vbroadcastf32x4/64x2 Vqq,Wq (66),(evo)
5409 +-1b: vbroadcastf32x8/64x4 Vqq,Mdq (66),(ev)
5410 +-1c: pabsb Pq,Qq | vpabsb Vx,Wx (66),(v1)
5411 +-1d: pabsw Pq,Qq | vpabsw Vx,Wx (66),(v1)
5412 +-1e: pabsd Pq,Qq | vpabsd Vx,Wx (66),(v1)
5413 +-1f: vpabsq Vx,Wx (66),(ev)
5414 +-# 0x0f 0x38 0x20-0x2f
5415 +-20: vpmovsxbw Vx,Ux/Mq (66),(v1) | vpmovswb Wx,Vx (F3),(ev)
5416 +-21: vpmovsxbd Vx,Ux/Md (66),(v1) | vpmovsdb Wx,Vd (F3),(ev)
5417 +-22: vpmovsxbq Vx,Ux/Mw (66),(v1) | vpmovsqb Wx,Vq (F3),(ev)
5418 +-23: vpmovsxwd Vx,Ux/Mq (66),(v1) | vpmovsdw Wx,Vd (F3),(ev)
5419 +-24: vpmovsxwq Vx,Ux/Md (66),(v1) | vpmovsqw Wx,Vq (F3),(ev)
5420 +-25: vpmovsxdq Vx,Ux/Mq (66),(v1) | vpmovsqd Wx,Vq (F3),(ev)
5421 +-26: vptestmb/w Vk,Hx,Wx (66),(ev) | vptestnmb/w Vk,Hx,Wx (F3),(ev)
5422 +-27: vptestmd/q Vk,Hx,Wx (66),(ev) | vptestnmd/q Vk,Hx,Wx (F3),(ev)
5423 +-28: vpmuldq Vx,Hx,Wx (66),(v1) | vpmovm2b/w Vx,Uk (F3),(ev)
5424 +-29: vpcmpeqq Vx,Hx,Wx (66),(v1) | vpmovb2m/w2m Vk,Ux (F3),(ev)
5425 +-2a: vmovntdqa Vx,Mx (66),(v1) | vpbroadcastmb2q Vx,Uk (F3),(ev)
5426 +-2b: vpackusdw Vx,Hx,Wx (66),(v1)
5427 +-2c: vmaskmovps Vx,Hx,Mx (66),(v) | vscalefps/d Vx,Hx,Wx (66),(evo)
5428 +-2d: vmaskmovpd Vx,Hx,Mx (66),(v) | vscalefss/d Vx,Hx,Wx (66),(evo)
5429 +-2e: vmaskmovps Mx,Hx,Vx (66),(v)
5430 +-2f: vmaskmovpd Mx,Hx,Vx (66),(v)
5431 +-# 0x0f 0x38 0x30-0x3f
5432 +-30: vpmovzxbw Vx,Ux/Mq (66),(v1) | vpmovwb Wx,Vx (F3),(ev)
5433 +-31: vpmovzxbd Vx,Ux/Md (66),(v1) | vpmovdb Wx,Vd (F3),(ev)
5434 +-32: vpmovzxbq Vx,Ux/Mw (66),(v1) | vpmovqb Wx,Vq (F3),(ev)
5435 +-33: vpmovzxwd Vx,Ux/Mq (66),(v1) | vpmovdw Wx,Vd (F3),(ev)
5436 +-34: vpmovzxwq Vx,Ux/Md (66),(v1) | vpmovqw Wx,Vq (F3),(ev)
5437 +-35: vpmovzxdq Vx,Ux/Mq (66),(v1) | vpmovqd Wx,Vq (F3),(ev)
5438 +-36: vpermd Vqq,Hqq,Wqq (66),(v) | vpermd/q Vqq,Hqq,Wqq (66),(evo)
5439 +-37: vpcmpgtq Vx,Hx,Wx (66),(v1)
5440 +-38: vpminsb Vx,Hx,Wx (66),(v1) | vpmovm2d/q Vx,Uk (F3),(ev)
5441 +-39: vpminsd Vx,Hx,Wx (66),(v1) | vpminsd/q Vx,Hx,Wx (66),(evo) | vpmovd2m/q2m Vk,Ux (F3),(ev)
5442 +-3a: vpminuw Vx,Hx,Wx (66),(v1) | vpbroadcastmw2d Vx,Uk (F3),(ev)
5443 +-3b: vpminud Vx,Hx,Wx (66),(v1) | vpminud/q Vx,Hx,Wx (66),(evo)
5444 +-3c: vpmaxsb Vx,Hx,Wx (66),(v1)
5445 +-3d: vpmaxsd Vx,Hx,Wx (66),(v1) | vpmaxsd/q Vx,Hx,Wx (66),(evo)
5446 +-3e: vpmaxuw Vx,Hx,Wx (66),(v1)
5447 +-3f: vpmaxud Vx,Hx,Wx (66),(v1) | vpmaxud/q Vx,Hx,Wx (66),(evo)
5448 +-# 0x0f 0x38 0x40-0x8f
5449 +-40: vpmulld Vx,Hx,Wx (66),(v1) | vpmulld/q Vx,Hx,Wx (66),(evo)
5450 +-41: vphminposuw Vdq,Wdq (66),(v1)
5451 +-42: vgetexpps/d Vx,Wx (66),(ev)
5452 +-43: vgetexpss/d Vx,Hx,Wx (66),(ev)
5453 +-44: vplzcntd/q Vx,Wx (66),(ev)
5454 +-45: vpsrlvd/q Vx,Hx,Wx (66),(v)
5455 +-46: vpsravd Vx,Hx,Wx (66),(v) | vpsravd/q Vx,Hx,Wx (66),(evo)
5456 +-47: vpsllvd/q Vx,Hx,Wx (66),(v)
5457 +-# Skip 0x48-0x4b
5458 +-4c: vrcp14ps/d Vpd,Wpd (66),(ev)
5459 +-4d: vrcp14ss/d Vsd,Hpd,Wsd (66),(ev)
5460 +-4e: vrsqrt14ps/d Vpd,Wpd (66),(ev)
5461 +-4f: vrsqrt14ss/d Vsd,Hsd,Wsd (66),(ev)
5462 +-# Skip 0x50-0x57
5463 +-58: vpbroadcastd Vx,Wx (66),(v)
5464 +-59: vpbroadcastq Vx,Wx (66),(v) | vbroadcasti32x2 Vx,Wx (66),(evo)
5465 +-5a: vbroadcasti128 Vqq,Mdq (66),(v) | vbroadcasti32x4/64x2 Vx,Wx (66),(evo)
5466 +-5b: vbroadcasti32x8/64x4 Vqq,Mdq (66),(ev)
5467 +-# Skip 0x5c-0x63
5468 +-64: vpblendmd/q Vx,Hx,Wx (66),(ev)
5469 +-65: vblendmps/d Vx,Hx,Wx (66),(ev)
5470 +-66: vpblendmb/w Vx,Hx,Wx (66),(ev)
5471 +-# Skip 0x67-0x74
5472 +-75: vpermi2b/w Vx,Hx,Wx (66),(ev)
5473 +-76: vpermi2d/q Vx,Hx,Wx (66),(ev)
5474 +-77: vpermi2ps/d Vx,Hx,Wx (66),(ev)
5475 +-78: vpbroadcastb Vx,Wx (66),(v)
5476 +-79: vpbroadcastw Vx,Wx (66),(v)
5477 +-7a: vpbroadcastb Vx,Rv (66),(ev)
5478 +-7b: vpbroadcastw Vx,Rv (66),(ev)
5479 +-7c: vpbroadcastd/q Vx,Rv (66),(ev)
5480 +-7d: vpermt2b/w Vx,Hx,Wx (66),(ev)
5481 +-7e: vpermt2d/q Vx,Hx,Wx (66),(ev)
5482 +-7f: vpermt2ps/d Vx,Hx,Wx (66),(ev)
5483 +-80: INVEPT Gy,Mdq (66)
5484 +-81: INVPID Gy,Mdq (66)
5485 +-82: INVPCID Gy,Mdq (66)
5486 +-83: vpmultishiftqb Vx,Hx,Wx (66),(ev)
5487 +-88: vexpandps/d Vpd,Wpd (66),(ev)
5488 +-89: vpexpandd/q Vx,Wx (66),(ev)
5489 +-8a: vcompressps/d Wx,Vx (66),(ev)
5490 +-8b: vpcompressd/q Wx,Vx (66),(ev)
5491 +-8c: vpmaskmovd/q Vx,Hx,Mx (66),(v)
5492 +-8d: vpermb/w Vx,Hx,Wx (66),(ev)
5493 +-8e: vpmaskmovd/q Mx,Vx,Hx (66),(v)
5494 +-# 0x0f 0x38 0x90-0xbf (FMA)
5495 +-90: vgatherdd/q Vx,Hx,Wx (66),(v) | vpgatherdd/q Vx,Wx (66),(evo)
5496 +-91: vgatherqd/q Vx,Hx,Wx (66),(v) | vpgatherqd/q Vx,Wx (66),(evo)
5497 +-92: vgatherdps/d Vx,Hx,Wx (66),(v)
5498 +-93: vgatherqps/d Vx,Hx,Wx (66),(v)
5499 +-94:
5500 +-95:
5501 +-96: vfmaddsub132ps/d Vx,Hx,Wx (66),(v)
5502 +-97: vfmsubadd132ps/d Vx,Hx,Wx (66),(v)
5503 +-98: vfmadd132ps/d Vx,Hx,Wx (66),(v)
5504 +-99: vfmadd132ss/d Vx,Hx,Wx (66),(v),(v1)
5505 +-9a: vfmsub132ps/d Vx,Hx,Wx (66),(v)
5506 +-9b: vfmsub132ss/d Vx,Hx,Wx (66),(v),(v1)
5507 +-9c: vfnmadd132ps/d Vx,Hx,Wx (66),(v)
5508 +-9d: vfnmadd132ss/d Vx,Hx,Wx (66),(v),(v1)
5509 +-9e: vfnmsub132ps/d Vx,Hx,Wx (66),(v)
5510 +-9f: vfnmsub132ss/d Vx,Hx,Wx (66),(v),(v1)
5511 +-a0: vpscatterdd/q Wx,Vx (66),(ev)
5512 +-a1: vpscatterqd/q Wx,Vx (66),(ev)
5513 +-a2: vscatterdps/d Wx,Vx (66),(ev)
5514 +-a3: vscatterqps/d Wx,Vx (66),(ev)
5515 +-a6: vfmaddsub213ps/d Vx,Hx,Wx (66),(v)
5516 +-a7: vfmsubadd213ps/d Vx,Hx,Wx (66),(v)
5517 +-a8: vfmadd213ps/d Vx,Hx,Wx (66),(v)
5518 +-a9: vfmadd213ss/d Vx,Hx,Wx (66),(v),(v1)
5519 +-aa: vfmsub213ps/d Vx,Hx,Wx (66),(v)
5520 +-ab: vfmsub213ss/d Vx,Hx,Wx (66),(v),(v1)
5521 +-ac: vfnmadd213ps/d Vx,Hx,Wx (66),(v)
5522 +-ad: vfnmadd213ss/d Vx,Hx,Wx (66),(v),(v1)
5523 +-ae: vfnmsub213ps/d Vx,Hx,Wx (66),(v)
5524 +-af: vfnmsub213ss/d Vx,Hx,Wx (66),(v),(v1)
5525 +-b4: vpmadd52luq Vx,Hx,Wx (66),(ev)
5526 +-b5: vpmadd52huq Vx,Hx,Wx (66),(ev)
5527 +-b6: vfmaddsub231ps/d Vx,Hx,Wx (66),(v)
5528 +-b7: vfmsubadd231ps/d Vx,Hx,Wx (66),(v)
5529 +-b8: vfmadd231ps/d Vx,Hx,Wx (66),(v)
5530 +-b9: vfmadd231ss/d Vx,Hx,Wx (66),(v),(v1)
5531 +-ba: vfmsub231ps/d Vx,Hx,Wx (66),(v)
5532 +-bb: vfmsub231ss/d Vx,Hx,Wx (66),(v),(v1)
5533 +-bc: vfnmadd231ps/d Vx,Hx,Wx (66),(v)
5534 +-bd: vfnmadd231ss/d Vx,Hx,Wx (66),(v),(v1)
5535 +-be: vfnmsub231ps/d Vx,Hx,Wx (66),(v)
5536 +-bf: vfnmsub231ss/d Vx,Hx,Wx (66),(v),(v1)
5537 +-# 0x0f 0x38 0xc0-0xff
5538 +-c4: vpconflictd/q Vx,Wx (66),(ev)
5539 +-c6: Grp18 (1A)
5540 +-c7: Grp19 (1A)
5541 +-c8: sha1nexte Vdq,Wdq | vexp2ps/d Vx,Wx (66),(ev)
5542 +-c9: sha1msg1 Vdq,Wdq
5543 +-ca: sha1msg2 Vdq,Wdq | vrcp28ps/d Vx,Wx (66),(ev)
5544 +-cb: sha256rnds2 Vdq,Wdq | vrcp28ss/d Vx,Hx,Wx (66),(ev)
5545 +-cc: sha256msg1 Vdq,Wdq | vrsqrt28ps/d Vx,Wx (66),(ev)
5546 +-cd: sha256msg2 Vdq,Wdq | vrsqrt28ss/d Vx,Hx,Wx (66),(ev)
5547 +-db: VAESIMC Vdq,Wdq (66),(v1)
5548 +-dc: VAESENC Vdq,Hdq,Wdq (66),(v1)
5549 +-dd: VAESENCLAST Vdq,Hdq,Wdq (66),(v1)
5550 +-de: VAESDEC Vdq,Hdq,Wdq (66),(v1)
5551 +-df: VAESDECLAST Vdq,Hdq,Wdq (66),(v1)
5552 +-f0: MOVBE Gy,My | MOVBE Gw,Mw (66) | CRC32 Gd,Eb (F2) | CRC32 Gd,Eb (66&F2)
5553 +-f1: MOVBE My,Gy | MOVBE Mw,Gw (66) | CRC32 Gd,Ey (F2) | CRC32 Gd,Ew (66&F2)
5554 +-f2: ANDN Gy,By,Ey (v)
5555 +-f3: Grp17 (1A)
5556 +-f5: BZHI Gy,Ey,By (v) | PEXT Gy,By,Ey (F3),(v) | PDEP Gy,By,Ey (F2),(v)
5557 +-f6: ADCX Gy,Ey (66) | ADOX Gy,Ey (F3) | MULX By,Gy,rDX,Ey (F2),(v)
5558 +-f7: BEXTR Gy,Ey,By (v) | SHLX Gy,Ey,By (66),(v) | SARX Gy,Ey,By (F3),(v) | SHRX Gy,Ey,By (F2),(v)
5559 +-EndTable
5560 +-
5561 +-Table: 3-byte opcode 2 (0x0f 0x3a)
5562 +-Referrer: 3-byte escape 2
5563 +-AVXcode: 3
5564 +-# 0x0f 0x3a 0x00-0xff
5565 +-00: vpermq Vqq,Wqq,Ib (66),(v)
5566 +-01: vpermpd Vqq,Wqq,Ib (66),(v)
5567 +-02: vpblendd Vx,Hx,Wx,Ib (66),(v)
5568 +-03: valignd/q Vx,Hx,Wx,Ib (66),(ev)
5569 +-04: vpermilps Vx,Wx,Ib (66),(v)
5570 +-05: vpermilpd Vx,Wx,Ib (66),(v)
5571 +-06: vperm2f128 Vqq,Hqq,Wqq,Ib (66),(v)
5572 +-07:
5573 +-08: vroundps Vx,Wx,Ib (66) | vrndscaleps Vx,Wx,Ib (66),(evo)
5574 +-09: vroundpd Vx,Wx,Ib (66) | vrndscalepd Vx,Wx,Ib (66),(evo)
5575 +-0a: vroundss Vss,Wss,Ib (66),(v1) | vrndscaless Vx,Hx,Wx,Ib (66),(evo)
5576 +-0b: vroundsd Vsd,Wsd,Ib (66),(v1) | vrndscalesd Vx,Hx,Wx,Ib (66),(evo)
5577 +-0c: vblendps Vx,Hx,Wx,Ib (66)
5578 +-0d: vblendpd Vx,Hx,Wx,Ib (66)
5579 +-0e: vpblendw Vx,Hx,Wx,Ib (66),(v1)
5580 +-0f: palignr Pq,Qq,Ib | vpalignr Vx,Hx,Wx,Ib (66),(v1)
5581 +-14: vpextrb Rd/Mb,Vdq,Ib (66),(v1)
5582 +-15: vpextrw Rd/Mw,Vdq,Ib (66),(v1)
5583 +-16: vpextrd/q Ey,Vdq,Ib (66),(v1)
5584 +-17: vextractps Ed,Vdq,Ib (66),(v1)
5585 +-18: vinsertf128 Vqq,Hqq,Wqq,Ib (66),(v) | vinsertf32x4/64x2 Vqq,Hqq,Wqq,Ib (66),(evo)
5586 +-19: vextractf128 Wdq,Vqq,Ib (66),(v) | vextractf32x4/64x2 Wdq,Vqq,Ib (66),(evo)
5587 +-1a: vinsertf32x8/64x4 Vqq,Hqq,Wqq,Ib (66),(ev)
5588 +-1b: vextractf32x8/64x4 Wdq,Vqq,Ib (66),(ev)
5589 +-1d: vcvtps2ph Wx,Vx,Ib (66),(v)
5590 +-1e: vpcmpud/q Vk,Hd,Wd,Ib (66),(ev)
5591 +-1f: vpcmpd/q Vk,Hd,Wd,Ib (66),(ev)
5592 +-20: vpinsrb Vdq,Hdq,Ry/Mb,Ib (66),(v1)
5593 +-21: vinsertps Vdq,Hdq,Udq/Md,Ib (66),(v1)
5594 +-22: vpinsrd/q Vdq,Hdq,Ey,Ib (66),(v1)
5595 +-23: vshuff32x4/64x2 Vx,Hx,Wx,Ib (66),(ev)
5596 +-25: vpternlogd/q Vx,Hx,Wx,Ib (66),(ev)
5597 +-26: vgetmantps/d Vx,Wx,Ib (66),(ev)
5598 +-27: vgetmantss/d Vx,Hx,Wx,Ib (66),(ev)
5599 +-30: kshiftrb/w Vk,Uk,Ib (66),(v)
5600 +-31: kshiftrd/q Vk,Uk,Ib (66),(v)
5601 +-32: kshiftlb/w Vk,Uk,Ib (66),(v)
5602 +-33: kshiftld/q Vk,Uk,Ib (66),(v)
5603 +-38: vinserti128 Vqq,Hqq,Wqq,Ib (66),(v) | vinserti32x4/64x2 Vqq,Hqq,Wqq,Ib (66),(evo)
5604 +-39: vextracti128 Wdq,Vqq,Ib (66),(v) | vextracti32x4/64x2 Wdq,Vqq,Ib (66),(evo)
5605 +-3a: vinserti32x8/64x4 Vqq,Hqq,Wqq,Ib (66),(ev)
5606 +-3b: vextracti32x8/64x4 Wdq,Vqq,Ib (66),(ev)
5607 +-3e: vpcmpub/w Vk,Hk,Wx,Ib (66),(ev)
5608 +-3f: vpcmpb/w Vk,Hk,Wx,Ib (66),(ev)
5609 +-40: vdpps Vx,Hx,Wx,Ib (66)
5610 +-41: vdppd Vdq,Hdq,Wdq,Ib (66),(v1)
5611 +-42: vmpsadbw Vx,Hx,Wx,Ib (66),(v1) | vdbpsadbw Vx,Hx,Wx,Ib (66),(evo)
5612 +-43: vshufi32x4/64x2 Vx,Hx,Wx,Ib (66),(ev)
5613 +-44: vpclmulqdq Vdq,Hdq,Wdq,Ib (66),(v1)
5614 +-46: vperm2i128 Vqq,Hqq,Wqq,Ib (66),(v)
5615 +-4a: vblendvps Vx,Hx,Wx,Lx (66),(v)
5616 +-4b: vblendvpd Vx,Hx,Wx,Lx (66),(v)
5617 +-4c: vpblendvb Vx,Hx,Wx,Lx (66),(v1)
5618 +-50: vrangeps/d Vx,Hx,Wx,Ib (66),(ev)
5619 +-51: vrangess/d Vx,Hx,Wx,Ib (66),(ev)
5620 +-54: vfixupimmps/d Vx,Hx,Wx,Ib (66),(ev)
5621 +-55: vfixupimmss/d Vx,Hx,Wx,Ib (66),(ev)
5622 +-56: vreduceps/d Vx,Wx,Ib (66),(ev)
5623 +-57: vreducess/d Vx,Hx,Wx,Ib (66),(ev)
5624 +-60: vpcmpestrm Vdq,Wdq,Ib (66),(v1)
5625 +-61: vpcmpestri Vdq,Wdq,Ib (66),(v1)
5626 +-62: vpcmpistrm Vdq,Wdq,Ib (66),(v1)
5627 +-63: vpcmpistri Vdq,Wdq,Ib (66),(v1)
5628 +-66: vfpclassps/d Vk,Wx,Ib (66),(ev)
5629 +-67: vfpclassss/d Vk,Wx,Ib (66),(ev)
5630 +-cc: sha1rnds4 Vdq,Wdq,Ib
5631 +-df: VAESKEYGEN Vdq,Wdq,Ib (66),(v1)
5632 +-f0: RORX Gy,Ey,Ib (F2),(v)
5633 +-EndTable
5634 +-
5635 +-GrpTable: Grp1
5636 +-0: ADD
5637 +-1: OR
5638 +-2: ADC
5639 +-3: SBB
5640 +-4: AND
5641 +-5: SUB
5642 +-6: XOR
5643 +-7: CMP
5644 +-EndTable
5645 +-
5646 +-GrpTable: Grp1A
5647 +-0: POP
5648 +-EndTable
5649 +-
5650 +-GrpTable: Grp2
5651 +-0: ROL
5652 +-1: ROR
5653 +-2: RCL
5654 +-3: RCR
5655 +-4: SHL/SAL
5656 +-5: SHR
5657 +-6:
5658 +-7: SAR
5659 +-EndTable
5660 +-
5661 +-GrpTable: Grp3_1
5662 +-0: TEST Eb,Ib
5663 +-1: TEST Eb,Ib
5664 +-2: NOT Eb
5665 +-3: NEG Eb
5666 +-4: MUL AL,Eb
5667 +-5: IMUL AL,Eb
5668 +-6: DIV AL,Eb
5669 +-7: IDIV AL,Eb
5670 +-EndTable
5671 +-
5672 +-GrpTable: Grp3_2
5673 +-0: TEST Ev,Iz
5674 +-1:
5675 +-2: NOT Ev
5676 +-3: NEG Ev
5677 +-4: MUL rAX,Ev
5678 +-5: IMUL rAX,Ev
5679 +-6: DIV rAX,Ev
5680 +-7: IDIV rAX,Ev
5681 +-EndTable
5682 +-
5683 +-GrpTable: Grp4
5684 +-0: INC Eb
5685 +-1: DEC Eb
5686 +-EndTable
5687 +-
5688 +-GrpTable: Grp5
5689 +-0: INC Ev
5690 +-1: DEC Ev
5691 +-# Note: "forced64" is Intel CPU behavior (see comment about CALL insn).
5692 +-2: CALLN Ev (f64)
5693 +-3: CALLF Ep
5694 +-4: JMPN Ev (f64)
5695 +-5: JMPF Mp
5696 +-6: PUSH Ev (d64)
5697 +-7:
5698 +-EndTable
5699 +-
5700 +-GrpTable: Grp6
5701 +-0: SLDT Rv/Mw
5702 +-1: STR Rv/Mw
5703 +-2: LLDT Ew
5704 +-3: LTR Ew
5705 +-4: VERR Ew
5706 +-5: VERW Ew
5707 +-EndTable
5708 +-
5709 +-GrpTable: Grp7
5710 +-0: SGDT Ms | VMCALL (001),(11B) | VMLAUNCH (010),(11B) | VMRESUME (011),(11B) | VMXOFF (100),(11B)
5711 +-1: SIDT Ms | MONITOR (000),(11B) | MWAIT (001),(11B) | CLAC (010),(11B) | STAC (011),(11B)
5712 +-2: LGDT Ms | XGETBV (000),(11B) | XSETBV (001),(11B) | VMFUNC (100),(11B) | XEND (101)(11B) | XTEST (110)(11B)
5713 +-3: LIDT Ms
5714 +-4: SMSW Mw/Rv
5715 +-5: rdpkru (110),(11B) | wrpkru (111),(11B)
5716 +-6: LMSW Ew
5717 +-7: INVLPG Mb | SWAPGS (o64),(000),(11B) | RDTSCP (001),(11B)
5718 +-EndTable
5719 +-
5720 +-GrpTable: Grp8
5721 +-4: BT
5722 +-5: BTS
5723 +-6: BTR
5724 +-7: BTC
5725 +-EndTable
5726 +-
5727 +-GrpTable: Grp9
5728 +-1: CMPXCHG8B/16B Mq/Mdq
5729 +-3: xrstors
5730 +-4: xsavec
5731 +-5: xsaves
5732 +-6: VMPTRLD Mq | VMCLEAR Mq (66) | VMXON Mq (F3) | RDRAND Rv (11B)
5733 +-7: VMPTRST Mq | VMPTRST Mq (F3) | RDSEED Rv (11B)
5734 +-EndTable
5735 +-
5736 +-GrpTable: Grp10
5737 +-EndTable
5738 +-
5739 +-# Grp11A and Grp11B are expressed as Grp11 in Intel SDM
5740 +-GrpTable: Grp11A
5741 +-0: MOV Eb,Ib
5742 +-7: XABORT Ib (000),(11B)
5743 +-EndTable
5744 +-
5745 +-GrpTable: Grp11B
5746 +-0: MOV Eb,Iz
5747 +-7: XBEGIN Jz (000),(11B)
5748 +-EndTable
5749 +-
5750 +-GrpTable: Grp12
5751 +-2: psrlw Nq,Ib (11B) | vpsrlw Hx,Ux,Ib (66),(11B),(v1)
5752 +-4: psraw Nq,Ib (11B) | vpsraw Hx,Ux,Ib (66),(11B),(v1)
5753 +-6: psllw Nq,Ib (11B) | vpsllw Hx,Ux,Ib (66),(11B),(v1)
5754 +-EndTable
5755 +-
5756 +-GrpTable: Grp13
5757 +-0: vprord/q Hx,Wx,Ib (66),(ev)
5758 +-1: vprold/q Hx,Wx,Ib (66),(ev)
5759 +-2: psrld Nq,Ib (11B) | vpsrld Hx,Ux,Ib (66),(11B),(v1)
5760 +-4: psrad Nq,Ib (11B) | vpsrad Hx,Ux,Ib (66),(11B),(v1) | vpsrad/q Hx,Ux,Ib (66),(evo)
5761 +-6: pslld Nq,Ib (11B) | vpslld Hx,Ux,Ib (66),(11B),(v1)
5762 +-EndTable
5763 +-
5764 +-GrpTable: Grp14
5765 +-2: psrlq Nq,Ib (11B) | vpsrlq Hx,Ux,Ib (66),(11B),(v1)
5766 +-3: vpsrldq Hx,Ux,Ib (66),(11B),(v1)
5767 +-6: psllq Nq,Ib (11B) | vpsllq Hx,Ux,Ib (66),(11B),(v1)
5768 +-7: vpslldq Hx,Ux,Ib (66),(11B),(v1)
5769 +-EndTable
5770 +-
5771 +-GrpTable: Grp15
5772 +-0: fxsave | RDFSBASE Ry (F3),(11B)
5773 +-1: fxstor | RDGSBASE Ry (F3),(11B)
5774 +-2: vldmxcsr Md (v1) | WRFSBASE Ry (F3),(11B)
5775 +-3: vstmxcsr Md (v1) | WRGSBASE Ry (F3),(11B)
5776 +-4: XSAVE
5777 +-5: XRSTOR | lfence (11B)
5778 +-6: XSAVEOPT | clwb (66) | mfence (11B)
5779 +-7: clflush | clflushopt (66) | sfence (11B)
5780 +-EndTable
5781 +-
5782 +-GrpTable: Grp16
5783 +-0: prefetch NTA
5784 +-1: prefetch T0
5785 +-2: prefetch T1
5786 +-3: prefetch T2
5787 +-EndTable
5788 +-
5789 +-GrpTable: Grp17
5790 +-1: BLSR By,Ey (v)
5791 +-2: BLSMSK By,Ey (v)
5792 +-3: BLSI By,Ey (v)
5793 +-EndTable
5794 +-
5795 +-GrpTable: Grp18
5796 +-1: vgatherpf0dps/d Wx (66),(ev)
5797 +-2: vgatherpf1dps/d Wx (66),(ev)
5798 +-5: vscatterpf0dps/d Wx (66),(ev)
5799 +-6: vscatterpf1dps/d Wx (66),(ev)
5800 +-EndTable
5801 +-
5802 +-GrpTable: Grp19
5803 +-1: vgatherpf0qps/d Wx (66),(ev)
5804 +-2: vgatherpf1qps/d Wx (66),(ev)
5805 +-5: vscatterpf0qps/d Wx (66),(ev)
5806 +-6: vscatterpf1qps/d Wx (66),(ev)
5807 +-EndTable
5808 +-
5809 +-# AMD's Prefetch Group
5810 +-GrpTable: GrpP
5811 +-0: PREFETCH
5812 +-1: PREFETCHW
5813 +-EndTable
5814 +-
5815 +-GrpTable: GrpPDLK
5816 +-0: MONTMUL
5817 +-1: XSHA1
5818 +-2: XSHA2
5819 +-EndTable
5820 +-
5821 +-GrpTable: GrpRNG
5822 +-0: xstore-rng
5823 +-1: xcrypt-ecb
5824 +-2: xcrypt-cbc
5825 +-4: xcrypt-cfb
5826 +-5: xcrypt-ofb
5827 +-EndTable
5828 +diff --git a/tools/objtool/arch/x86/lib/inat.c b/tools/objtool/arch/x86/lib/inat.c
5829 +new file mode 100644
5830 +index 000000000000..c1f01a8e9f65
5831 +--- /dev/null
5832 ++++ b/tools/objtool/arch/x86/lib/inat.c
5833 +@@ -0,0 +1,97 @@
5834 ++/*
5835 ++ * x86 instruction attribute tables
5836 ++ *
5837 ++ * Written by Masami Hiramatsu <mhiramat@××××××.com>
5838 ++ *
5839 ++ * This program is free software; you can redistribute it and/or modify
5840 ++ * it under the terms of the GNU General Public License as published by
5841 ++ * the Free Software Foundation; either version 2 of the License, or
5842 ++ * (at your option) any later version.
5843 ++ *
5844 ++ * This program is distributed in the hope that it will be useful,
5845 ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
5846 ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5847 ++ * GNU General Public License for more details.
5848 ++ *
5849 ++ * You should have received a copy of the GNU General Public License
5850 ++ * along with this program; if not, write to the Free Software
5851 ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
5852 ++ *
5853 ++ */
5854 ++#include <asm/insn.h>
5855 ++
5856 ++/* Attribute tables are generated from opcode map */
5857 ++#include "inat-tables.c"
5858 ++
5859 ++/* Attribute search APIs */
5860 ++insn_attr_t inat_get_opcode_attribute(insn_byte_t opcode)
5861 ++{
5862 ++ return inat_primary_table[opcode];
5863 ++}
5864 ++
5865 ++int inat_get_last_prefix_id(insn_byte_t last_pfx)
5866 ++{
5867 ++ insn_attr_t lpfx_attr;
5868 ++
5869 ++ lpfx_attr = inat_get_opcode_attribute(last_pfx);
5870 ++ return inat_last_prefix_id(lpfx_attr);
5871 ++}
5872 ++
5873 ++insn_attr_t inat_get_escape_attribute(insn_byte_t opcode, int lpfx_id,
5874 ++ insn_attr_t esc_attr)
5875 ++{
5876 ++ const insn_attr_t *table;
5877 ++ int n;
5878 ++
5879 ++ n = inat_escape_id(esc_attr);
5880 ++
5881 ++ table = inat_escape_tables[n][0];
5882 ++ if (!table)
5883 ++ return 0;
5884 ++ if (inat_has_variant(table[opcode]) && lpfx_id) {
5885 ++ table = inat_escape_tables[n][lpfx_id];
5886 ++ if (!table)
5887 ++ return 0;
5888 ++ }
5889 ++ return table[opcode];
5890 ++}
5891 ++
5892 ++insn_attr_t inat_get_group_attribute(insn_byte_t modrm, int lpfx_id,
5893 ++ insn_attr_t grp_attr)
5894 ++{
5895 ++ const insn_attr_t *table;
5896 ++ int n;
5897 ++
5898 ++ n = inat_group_id(grp_attr);
5899 ++
5900 ++ table = inat_group_tables[n][0];
5901 ++ if (!table)
5902 ++ return inat_group_common_attribute(grp_attr);
5903 ++ if (inat_has_variant(table[X86_MODRM_REG(modrm)]) && lpfx_id) {
5904 ++ table = inat_group_tables[n][lpfx_id];
5905 ++ if (!table)
5906 ++ return inat_group_common_attribute(grp_attr);
5907 ++ }
5908 ++ return table[X86_MODRM_REG(modrm)] |
5909 ++ inat_group_common_attribute(grp_attr);
5910 ++}
5911 ++
5912 ++insn_attr_t inat_get_avx_attribute(insn_byte_t opcode, insn_byte_t vex_m,
5913 ++ insn_byte_t vex_p)
5914 ++{
5915 ++ const insn_attr_t *table;
5916 ++ if (vex_m > X86_VEX_M_MAX || vex_p > INAT_LSTPFX_MAX)
5917 ++ return 0;
5918 ++ /* At first, this checks the master table */
5919 ++ table = inat_avx_tables[vex_m][0];
5920 ++ if (!table)
5921 ++ return 0;
5922 ++ if (!inat_is_group(table[opcode]) && vex_p) {
5923 ++ /* If this is not a group, get attribute directly */
5924 ++ table = inat_avx_tables[vex_m][vex_p];
5925 ++ if (!table)
5926 ++ return 0;
5927 ++ }
5928 ++ return table[opcode];
5929 ++}
5930 ++
5931 +diff --git a/tools/objtool/arch/x86/lib/insn.c b/tools/objtool/arch/x86/lib/insn.c
5932 +new file mode 100644
5933 +index 000000000000..1088eb8f3a5f
5934 +--- /dev/null
5935 ++++ b/tools/objtool/arch/x86/lib/insn.c
5936 +@@ -0,0 +1,606 @@
5937 ++/*
5938 ++ * x86 instruction analysis
5939 ++ *
5940 ++ * This program is free software; you can redistribute it and/or modify
5941 ++ * it under the terms of the GNU General Public License as published by
5942 ++ * the Free Software Foundation; either version 2 of the License, or
5943 ++ * (at your option) any later version.
5944 ++ *
5945 ++ * This program is distributed in the hope that it will be useful,
5946 ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
5947 ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5948 ++ * GNU General Public License for more details.
5949 ++ *
5950 ++ * You should have received a copy of the GNU General Public License
5951 ++ * along with this program; if not, write to the Free Software
5952 ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
5953 ++ *
5954 ++ * Copyright (C) IBM Corporation, 2002, 2004, 2009
5955 ++ */
5956 ++
5957 ++#ifdef __KERNEL__
5958 ++#include <linux/string.h>
5959 ++#else
5960 ++#include <string.h>
5961 ++#endif
5962 ++#include <asm/inat.h>
5963 ++#include <asm/insn.h>
5964 ++
5965 ++/* Verify next sizeof(t) bytes can be on the same instruction */
5966 ++#define validate_next(t, insn, n) \
5967 ++ ((insn)->next_byte + sizeof(t) + n <= (insn)->end_kaddr)
5968 ++
5969 ++#define __get_next(t, insn) \
5970 ++ ({ t r = *(t*)insn->next_byte; insn->next_byte += sizeof(t); r; })
5971 ++
5972 ++#define __peek_nbyte_next(t, insn, n) \
5973 ++ ({ t r = *(t*)((insn)->next_byte + n); r; })
5974 ++
5975 ++#define get_next(t, insn) \
5976 ++ ({ if (unlikely(!validate_next(t, insn, 0))) goto err_out; __get_next(t, insn); })
5977 ++
5978 ++#define peek_nbyte_next(t, insn, n) \
5979 ++ ({ if (unlikely(!validate_next(t, insn, n))) goto err_out; __peek_nbyte_next(t, insn, n); })
5980 ++
5981 ++#define peek_next(t, insn) peek_nbyte_next(t, insn, 0)
5982 ++
5983 ++/**
5984 ++ * insn_init() - initialize struct insn
5985 ++ * @insn: &struct insn to be initialized
5986 ++ * @kaddr: address (in kernel memory) of instruction (or copy thereof)
5987 ++ * @x86_64: !0 for 64-bit kernel or 64-bit app
5988 ++ */
5989 ++void insn_init(struct insn *insn, const void *kaddr, int buf_len, int x86_64)
5990 ++{
5991 ++ /*
5992 ++ * Instructions longer than MAX_INSN_SIZE (15 bytes) are invalid
5993 ++ * even if the input buffer is long enough to hold them.
5994 ++ */
5995 ++ if (buf_len > MAX_INSN_SIZE)
5996 ++ buf_len = MAX_INSN_SIZE;
5997 ++
5998 ++ memset(insn, 0, sizeof(*insn));
5999 ++ insn->kaddr = kaddr;
6000 ++ insn->end_kaddr = kaddr + buf_len;
6001 ++ insn->next_byte = kaddr;
6002 ++ insn->x86_64 = x86_64 ? 1 : 0;
6003 ++ insn->opnd_bytes = 4;
6004 ++ if (x86_64)
6005 ++ insn->addr_bytes = 8;
6006 ++ else
6007 ++ insn->addr_bytes = 4;
6008 ++}
6009 ++
6010 ++/**
6011 ++ * insn_get_prefixes - scan x86 instruction prefix bytes
6012 ++ * @insn: &struct insn containing instruction
6013 ++ *
6014 ++ * Populates the @insn->prefixes bitmap, and updates @insn->next_byte
6015 ++ * to point to the (first) opcode. No effect if @insn->prefixes.got
6016 ++ * is already set.
6017 ++ */
6018 ++void insn_get_prefixes(struct insn *insn)
6019 ++{
6020 ++ struct insn_field *prefixes = &insn->prefixes;
6021 ++ insn_attr_t attr;
6022 ++ insn_byte_t b, lb;
6023 ++ int i, nb;
6024 ++
6025 ++ if (prefixes->got)
6026 ++ return;
6027 ++
6028 ++ nb = 0;
6029 ++ lb = 0;
6030 ++ b = peek_next(insn_byte_t, insn);
6031 ++ attr = inat_get_opcode_attribute(b);
6032 ++ while (inat_is_legacy_prefix(attr)) {
6033 ++ /* Skip if same prefix */
6034 ++ for (i = 0; i < nb; i++)
6035 ++ if (prefixes->bytes[i] == b)
6036 ++ goto found;
6037 ++ if (nb == 4)
6038 ++ /* Invalid instruction */
6039 ++ break;
6040 ++ prefixes->bytes[nb++] = b;
6041 ++ if (inat_is_address_size_prefix(attr)) {
6042 ++ /* address size switches 2/4 or 4/8 */
6043 ++ if (insn->x86_64)
6044 ++ insn->addr_bytes ^= 12;
6045 ++ else
6046 ++ insn->addr_bytes ^= 6;
6047 ++ } else if (inat_is_operand_size_prefix(attr)) {
6048 ++ /* oprand size switches 2/4 */
6049 ++ insn->opnd_bytes ^= 6;
6050 ++ }
6051 ++found:
6052 ++ prefixes->nbytes++;
6053 ++ insn->next_byte++;
6054 ++ lb = b;
6055 ++ b = peek_next(insn_byte_t, insn);
6056 ++ attr = inat_get_opcode_attribute(b);
6057 ++ }
6058 ++ /* Set the last prefix */
6059 ++ if (lb && lb != insn->prefixes.bytes[3]) {
6060 ++ if (unlikely(insn->prefixes.bytes[3])) {
6061 ++ /* Swap the last prefix */
6062 ++ b = insn->prefixes.bytes[3];
6063 ++ for (i = 0; i < nb; i++)
6064 ++ if (prefixes->bytes[i] == lb)
6065 ++ prefixes->bytes[i] = b;
6066 ++ }
6067 ++ insn->prefixes.bytes[3] = lb;
6068 ++ }
6069 ++
6070 ++ /* Decode REX prefix */
6071 ++ if (insn->x86_64) {
6072 ++ b = peek_next(insn_byte_t, insn);
6073 ++ attr = inat_get_opcode_attribute(b);
6074 ++ if (inat_is_rex_prefix(attr)) {
6075 ++ insn->rex_prefix.value = b;
6076 ++ insn->rex_prefix.nbytes = 1;
6077 ++ insn->next_byte++;
6078 ++ if (X86_REX_W(b))
6079 ++ /* REX.W overrides opnd_size */
6080 ++ insn->opnd_bytes = 8;
6081 ++ }
6082 ++ }
6083 ++ insn->rex_prefix.got = 1;
6084 ++
6085 ++ /* Decode VEX prefix */
6086 ++ b = peek_next(insn_byte_t, insn);
6087 ++ attr = inat_get_opcode_attribute(b);
6088 ++ if (inat_is_vex_prefix(attr)) {
6089 ++ insn_byte_t b2 = peek_nbyte_next(insn_byte_t, insn, 1);
6090 ++ if (!insn->x86_64) {
6091 ++ /*
6092 ++ * In 32-bits mode, if the [7:6] bits (mod bits of
6093 ++ * ModRM) on the second byte are not 11b, it is
6094 ++ * LDS or LES or BOUND.
6095 ++ */
6096 ++ if (X86_MODRM_MOD(b2) != 3)
6097 ++ goto vex_end;
6098 ++ }
6099 ++ insn->vex_prefix.bytes[0] = b;
6100 ++ insn->vex_prefix.bytes[1] = b2;
6101 ++ if (inat_is_evex_prefix(attr)) {
6102 ++ b2 = peek_nbyte_next(insn_byte_t, insn, 2);
6103 ++ insn->vex_prefix.bytes[2] = b2;
6104 ++ b2 = peek_nbyte_next(insn_byte_t, insn, 3);
6105 ++ insn->vex_prefix.bytes[3] = b2;
6106 ++ insn->vex_prefix.nbytes = 4;
6107 ++ insn->next_byte += 4;
6108 ++ if (insn->x86_64 && X86_VEX_W(b2))
6109 ++ /* VEX.W overrides opnd_size */
6110 ++ insn->opnd_bytes = 8;
6111 ++ } else if (inat_is_vex3_prefix(attr)) {
6112 ++ b2 = peek_nbyte_next(insn_byte_t, insn, 2);
6113 ++ insn->vex_prefix.bytes[2] = b2;
6114 ++ insn->vex_prefix.nbytes = 3;
6115 ++ insn->next_byte += 3;
6116 ++ if (insn->x86_64 && X86_VEX_W(b2))
6117 ++ /* VEX.W overrides opnd_size */
6118 ++ insn->opnd_bytes = 8;
6119 ++ } else {
6120 ++ /*
6121 ++ * For VEX2, fake VEX3-like byte#2.
6122 ++ * Makes it easier to decode vex.W, vex.vvvv,
6123 ++ * vex.L and vex.pp. Masking with 0x7f sets vex.W == 0.
6124 ++ */
6125 ++ insn->vex_prefix.bytes[2] = b2 & 0x7f;
6126 ++ insn->vex_prefix.nbytes = 2;
6127 ++ insn->next_byte += 2;
6128 ++ }
6129 ++ }
6130 ++vex_end:
6131 ++ insn->vex_prefix.got = 1;
6132 ++
6133 ++ prefixes->got = 1;
6134 ++
6135 ++err_out:
6136 ++ return;
6137 ++}
6138 ++
6139 ++/**
6140 ++ * insn_get_opcode - collect opcode(s)
6141 ++ * @insn: &struct insn containing instruction
6142 ++ *
6143 ++ * Populates @insn->opcode, updates @insn->next_byte to point past the
6144 ++ * opcode byte(s), and set @insn->attr (except for groups).
6145 ++ * If necessary, first collects any preceding (prefix) bytes.
6146 ++ * Sets @insn->opcode.value = opcode1. No effect if @insn->opcode.got
6147 ++ * is already 1.
6148 ++ */
6149 ++void insn_get_opcode(struct insn *insn)
6150 ++{
6151 ++ struct insn_field *opcode = &insn->opcode;
6152 ++ insn_byte_t op;
6153 ++ int pfx_id;
6154 ++ if (opcode->got)
6155 ++ return;
6156 ++ if (!insn->prefixes.got)
6157 ++ insn_get_prefixes(insn);
6158 ++
6159 ++ /* Get first opcode */
6160 ++ op = get_next(insn_byte_t, insn);
6161 ++ opcode->bytes[0] = op;
6162 ++ opcode->nbytes = 1;
6163 ++
6164 ++ /* Check if there is VEX prefix or not */
6165 ++ if (insn_is_avx(insn)) {
6166 ++ insn_byte_t m, p;
6167 ++ m = insn_vex_m_bits(insn);
6168 ++ p = insn_vex_p_bits(insn);
6169 ++ insn->attr = inat_get_avx_attribute(op, m, p);
6170 ++ if ((inat_must_evex(insn->attr) && !insn_is_evex(insn)) ||
6171 ++ (!inat_accept_vex(insn->attr) &&
6172 ++ !inat_is_group(insn->attr)))
6173 ++ insn->attr = 0; /* This instruction is bad */
6174 ++ goto end; /* VEX has only 1 byte for opcode */
6175 ++ }
6176 ++
6177 ++ insn->attr = inat_get_opcode_attribute(op);
6178 ++ while (inat_is_escape(insn->attr)) {
6179 ++ /* Get escaped opcode */
6180 ++ op = get_next(insn_byte_t, insn);
6181 ++ opcode->bytes[opcode->nbytes++] = op;
6182 ++ pfx_id = insn_last_prefix_id(insn);
6183 ++ insn->attr = inat_get_escape_attribute(op, pfx_id, insn->attr);
6184 ++ }
6185 ++ if (inat_must_vex(insn->attr))
6186 ++ insn->attr = 0; /* This instruction is bad */
6187 ++end:
6188 ++ opcode->got = 1;
6189 ++
6190 ++err_out:
6191 ++ return;
6192 ++}
6193 ++
6194 ++/**
6195 ++ * insn_get_modrm - collect ModRM byte, if any
6196 ++ * @insn: &struct insn containing instruction
6197 ++ *
6198 ++ * Populates @insn->modrm and updates @insn->next_byte to point past the
6199 ++ * ModRM byte, if any. If necessary, first collects the preceding bytes
6200 ++ * (prefixes and opcode(s)). No effect if @insn->modrm.got is already 1.
6201 ++ */
6202 ++void insn_get_modrm(struct insn *insn)
6203 ++{
6204 ++ struct insn_field *modrm = &insn->modrm;
6205 ++ insn_byte_t pfx_id, mod;
6206 ++ if (modrm->got)
6207 ++ return;
6208 ++ if (!insn->opcode.got)
6209 ++ insn_get_opcode(insn);
6210 ++
6211 ++ if (inat_has_modrm(insn->attr)) {
6212 ++ mod = get_next(insn_byte_t, insn);
6213 ++ modrm->value = mod;
6214 ++ modrm->nbytes = 1;
6215 ++ if (inat_is_group(insn->attr)) {
6216 ++ pfx_id = insn_last_prefix_id(insn);
6217 ++ insn->attr = inat_get_group_attribute(mod, pfx_id,
6218 ++ insn->attr);
6219 ++ if (insn_is_avx(insn) && !inat_accept_vex(insn->attr))
6220 ++ insn->attr = 0; /* This is bad */
6221 ++ }
6222 ++ }
6223 ++
6224 ++ if (insn->x86_64 && inat_is_force64(insn->attr))
6225 ++ insn->opnd_bytes = 8;
6226 ++ modrm->got = 1;
6227 ++
6228 ++err_out:
6229 ++ return;
6230 ++}
6231 ++
6232 ++
6233 ++/**
6234 ++ * insn_rip_relative() - Does instruction use RIP-relative addressing mode?
6235 ++ * @insn: &struct insn containing instruction
6236 ++ *
6237 ++ * If necessary, first collects the instruction up to and including the
6238 ++ * ModRM byte. No effect if @insn->x86_64 is 0.
6239 ++ */
6240 ++int insn_rip_relative(struct insn *insn)
6241 ++{
6242 ++ struct insn_field *modrm = &insn->modrm;
6243 ++
6244 ++ if (!insn->x86_64)
6245 ++ return 0;
6246 ++ if (!modrm->got)
6247 ++ insn_get_modrm(insn);
6248 ++ /*
6249 ++ * For rip-relative instructions, the mod field (top 2 bits)
6250 ++ * is zero and the r/m field (bottom 3 bits) is 0x5.
6251 ++ */
6252 ++ return (modrm->nbytes && (modrm->value & 0xc7) == 0x5);
6253 ++}
6254 ++
6255 ++/**
6256 ++ * insn_get_sib() - Get the SIB byte of instruction
6257 ++ * @insn: &struct insn containing instruction
6258 ++ *
6259 ++ * If necessary, first collects the instruction up to and including the
6260 ++ * ModRM byte.
6261 ++ */
6262 ++void insn_get_sib(struct insn *insn)
6263 ++{
6264 ++ insn_byte_t modrm;
6265 ++
6266 ++ if (insn->sib.got)
6267 ++ return;
6268 ++ if (!insn->modrm.got)
6269 ++ insn_get_modrm(insn);
6270 ++ if (insn->modrm.nbytes) {
6271 ++ modrm = (insn_byte_t)insn->modrm.value;
6272 ++ if (insn->addr_bytes != 2 &&
6273 ++ X86_MODRM_MOD(modrm) != 3 && X86_MODRM_RM(modrm) == 4) {
6274 ++ insn->sib.value = get_next(insn_byte_t, insn);
6275 ++ insn->sib.nbytes = 1;
6276 ++ }
6277 ++ }
6278 ++ insn->sib.got = 1;
6279 ++
6280 ++err_out:
6281 ++ return;
6282 ++}
6283 ++
6284 ++
6285 ++/**
6286 ++ * insn_get_displacement() - Get the displacement of instruction
6287 ++ * @insn: &struct insn containing instruction
6288 ++ *
6289 ++ * If necessary, first collects the instruction up to and including the
6290 ++ * SIB byte.
6291 ++ * Displacement value is sign-expanded.
6292 ++ */
6293 ++void insn_get_displacement(struct insn *insn)
6294 ++{
6295 ++ insn_byte_t mod, rm, base;
6296 ++
6297 ++ if (insn->displacement.got)
6298 ++ return;
6299 ++ if (!insn->sib.got)
6300 ++ insn_get_sib(insn);
6301 ++ if (insn->modrm.nbytes) {
6302 ++ /*
6303 ++ * Interpreting the modrm byte:
6304 ++ * mod = 00 - no displacement fields (exceptions below)
6305 ++ * mod = 01 - 1-byte displacement field
6306 ++ * mod = 10 - displacement field is 4 bytes, or 2 bytes if
6307 ++ * address size = 2 (0x67 prefix in 32-bit mode)
6308 ++ * mod = 11 - no memory operand
6309 ++ *
6310 ++ * If address size = 2...
6311 ++ * mod = 00, r/m = 110 - displacement field is 2 bytes
6312 ++ *
6313 ++ * If address size != 2...
6314 ++ * mod != 11, r/m = 100 - SIB byte exists
6315 ++ * mod = 00, SIB base = 101 - displacement field is 4 bytes
6316 ++ * mod = 00, r/m = 101 - rip-relative addressing, displacement
6317 ++ * field is 4 bytes
6318 ++ */
6319 ++ mod = X86_MODRM_MOD(insn->modrm.value);
6320 ++ rm = X86_MODRM_RM(insn->modrm.value);
6321 ++ base = X86_SIB_BASE(insn->sib.value);
6322 ++ if (mod == 3)
6323 ++ goto out;
6324 ++ if (mod == 1) {
6325 ++ insn->displacement.value = get_next(signed char, insn);
6326 ++ insn->displacement.nbytes = 1;
6327 ++ } else if (insn->addr_bytes == 2) {
6328 ++ if ((mod == 0 && rm == 6) || mod == 2) {
6329 ++ insn->displacement.value =
6330 ++ get_next(short, insn);
6331 ++ insn->displacement.nbytes = 2;
6332 ++ }
6333 ++ } else {
6334 ++ if ((mod == 0 && rm == 5) || mod == 2 ||
6335 ++ (mod == 0 && base == 5)) {
6336 ++ insn->displacement.value = get_next(int, insn);
6337 ++ insn->displacement.nbytes = 4;
6338 ++ }
6339 ++ }
6340 ++ }
6341 ++out:
6342 ++ insn->displacement.got = 1;
6343 ++
6344 ++err_out:
6345 ++ return;
6346 ++}
6347 ++
6348 ++/* Decode moffset16/32/64. Return 0 if failed */
6349 ++static int __get_moffset(struct insn *insn)
6350 ++{
6351 ++ switch (insn->addr_bytes) {
6352 ++ case 2:
6353 ++ insn->moffset1.value = get_next(short, insn);
6354 ++ insn->moffset1.nbytes = 2;
6355 ++ break;
6356 ++ case 4:
6357 ++ insn->moffset1.value = get_next(int, insn);
6358 ++ insn->moffset1.nbytes = 4;
6359 ++ break;
6360 ++ case 8:
6361 ++ insn->moffset1.value = get_next(int, insn);
6362 ++ insn->moffset1.nbytes = 4;
6363 ++ insn->moffset2.value = get_next(int, insn);
6364 ++ insn->moffset2.nbytes = 4;
6365 ++ break;
6366 ++ default: /* opnd_bytes must be modified manually */
6367 ++ goto err_out;
6368 ++ }
6369 ++ insn->moffset1.got = insn->moffset2.got = 1;
6370 ++
6371 ++ return 1;
6372 ++
6373 ++err_out:
6374 ++ return 0;
6375 ++}
6376 ++
6377 ++/* Decode imm v32(Iz). Return 0 if failed */
6378 ++static int __get_immv32(struct insn *insn)
6379 ++{
6380 ++ switch (insn->opnd_bytes) {
6381 ++ case 2:
6382 ++ insn->immediate.value = get_next(short, insn);
6383 ++ insn->immediate.nbytes = 2;
6384 ++ break;
6385 ++ case 4:
6386 ++ case 8:
6387 ++ insn->immediate.value = get_next(int, insn);
6388 ++ insn->immediate.nbytes = 4;
6389 ++ break;
6390 ++ default: /* opnd_bytes must be modified manually */
6391 ++ goto err_out;
6392 ++ }
6393 ++
6394 ++ return 1;
6395 ++
6396 ++err_out:
6397 ++ return 0;
6398 ++}
6399 ++
6400 ++/* Decode imm v64(Iv/Ov), Return 0 if failed */
6401 ++static int __get_immv(struct insn *insn)
6402 ++{
6403 ++ switch (insn->opnd_bytes) {
6404 ++ case 2:
6405 ++ insn->immediate1.value = get_next(short, insn);
6406 ++ insn->immediate1.nbytes = 2;
6407 ++ break;
6408 ++ case 4:
6409 ++ insn->immediate1.value = get_next(int, insn);
6410 ++ insn->immediate1.nbytes = 4;
6411 ++ break;
6412 ++ case 8:
6413 ++ insn->immediate1.value = get_next(int, insn);
6414 ++ insn->immediate1.nbytes = 4;
6415 ++ insn->immediate2.value = get_next(int, insn);
6416 ++ insn->immediate2.nbytes = 4;
6417 ++ break;
6418 ++ default: /* opnd_bytes must be modified manually */
6419 ++ goto err_out;
6420 ++ }
6421 ++ insn->immediate1.got = insn->immediate2.got = 1;
6422 ++
6423 ++ return 1;
6424 ++err_out:
6425 ++ return 0;
6426 ++}
6427 ++
6428 ++/* Decode ptr16:16/32(Ap) */
6429 ++static int __get_immptr(struct insn *insn)
6430 ++{
6431 ++ switch (insn->opnd_bytes) {
6432 ++ case 2:
6433 ++ insn->immediate1.value = get_next(short, insn);
6434 ++ insn->immediate1.nbytes = 2;
6435 ++ break;
6436 ++ case 4:
6437 ++ insn->immediate1.value = get_next(int, insn);
6438 ++ insn->immediate1.nbytes = 4;
6439 ++ break;
6440 ++ case 8:
6441 ++ /* ptr16:64 is not exist (no segment) */
6442 ++ return 0;
6443 ++ default: /* opnd_bytes must be modified manually */
6444 ++ goto err_out;
6445 ++ }
6446 ++ insn->immediate2.value = get_next(unsigned short, insn);
6447 ++ insn->immediate2.nbytes = 2;
6448 ++ insn->immediate1.got = insn->immediate2.got = 1;
6449 ++
6450 ++ return 1;
6451 ++err_out:
6452 ++ return 0;
6453 ++}
6454 ++
6455 ++/**
6456 ++ * insn_get_immediate() - Get the immediates of instruction
6457 ++ * @insn: &struct insn containing instruction
6458 ++ *
6459 ++ * If necessary, first collects the instruction up to and including the
6460 ++ * displacement bytes.
6461 ++ * Basically, most of immediates are sign-expanded. Unsigned-value can be
6462 ++ * get by bit masking with ((1 << (nbytes * 8)) - 1)
6463 ++ */
6464 ++void insn_get_immediate(struct insn *insn)
6465 ++{
6466 ++ if (insn->immediate.got)
6467 ++ return;
6468 ++ if (!insn->displacement.got)
6469 ++ insn_get_displacement(insn);
6470 ++
6471 ++ if (inat_has_moffset(insn->attr)) {
6472 ++ if (!__get_moffset(insn))
6473 ++ goto err_out;
6474 ++ goto done;
6475 ++ }
6476 ++
6477 ++ if (!inat_has_immediate(insn->attr))
6478 ++ /* no immediates */
6479 ++ goto done;
6480 ++
6481 ++ switch (inat_immediate_size(insn->attr)) {
6482 ++ case INAT_IMM_BYTE:
6483 ++ insn->immediate.value = get_next(signed char, insn);
6484 ++ insn->immediate.nbytes = 1;
6485 ++ break;
6486 ++ case INAT_IMM_WORD:
6487 ++ insn->immediate.value = get_next(short, insn);
6488 ++ insn->immediate.nbytes = 2;
6489 ++ break;
6490 ++ case INAT_IMM_DWORD:
6491 ++ insn->immediate.value = get_next(int, insn);
6492 ++ insn->immediate.nbytes = 4;
6493 ++ break;
6494 ++ case INAT_IMM_QWORD:
6495 ++ insn->immediate1.value = get_next(int, insn);
6496 ++ insn->immediate1.nbytes = 4;
6497 ++ insn->immediate2.value = get_next(int, insn);
6498 ++ insn->immediate2.nbytes = 4;
6499 ++ break;
6500 ++ case INAT_IMM_PTR:
6501 ++ if (!__get_immptr(insn))
6502 ++ goto err_out;
6503 ++ break;
6504 ++ case INAT_IMM_VWORD32:
6505 ++ if (!__get_immv32(insn))
6506 ++ goto err_out;
6507 ++ break;
6508 ++ case INAT_IMM_VWORD:
6509 ++ if (!__get_immv(insn))
6510 ++ goto err_out;
6511 ++ break;
6512 ++ default:
6513 ++ /* Here, insn must have an immediate, but failed */
6514 ++ goto err_out;
6515 ++ }
6516 ++ if (inat_has_second_immediate(insn->attr)) {
6517 ++ insn->immediate2.value = get_next(signed char, insn);
6518 ++ insn->immediate2.nbytes = 1;
6519 ++ }
6520 ++done:
6521 ++ insn->immediate.got = 1;
6522 ++
6523 ++err_out:
6524 ++ return;
6525 ++}
6526 ++
6527 ++/**
6528 ++ * insn_get_length() - Get the length of instruction
6529 ++ * @insn: &struct insn containing instruction
6530 ++ *
6531 ++ * If necessary, first collects the instruction up to and including the
6532 ++ * immediates bytes.
6533 ++ */
6534 ++void insn_get_length(struct insn *insn)
6535 ++{
6536 ++ if (insn->length)
6537 ++ return;
6538 ++ if (!insn->immediate.got)
6539 ++ insn_get_immediate(insn);
6540 ++ insn->length = (unsigned char)((unsigned long)insn->next_byte
6541 ++ - (unsigned long)insn->kaddr);
6542 ++}
6543 +diff --git a/tools/objtool/arch/x86/lib/x86-opcode-map.txt b/tools/objtool/arch/x86/lib/x86-opcode-map.txt
6544 +new file mode 100644
6545 +index 000000000000..1754e094bc28
6546 +--- /dev/null
6547 ++++ b/tools/objtool/arch/x86/lib/x86-opcode-map.txt
6548 +@@ -0,0 +1,1063 @@
6549 ++# x86 Opcode Maps
6550 ++#
6551 ++# This is (mostly) based on following documentations.
6552 ++# - Intel(R) 64 and IA-32 Architectures Software Developer's Manual Vol.2C
6553 ++# (#326018-047US, June 2013)
6554 ++#
6555 ++#<Opcode maps>
6556 ++# Table: table-name
6557 ++# Referrer: escaped-name
6558 ++# AVXcode: avx-code
6559 ++# opcode: mnemonic|GrpXXX [operand1[,operand2...]] [(extra1)[,(extra2)...] [| 2nd-mnemonic ...]
6560 ++# (or)
6561 ++# opcode: escape # escaped-name
6562 ++# EndTable
6563 ++#
6564 ++# mnemonics that begin with lowercase 'v' accept a VEX or EVEX prefix
6565 ++# mnemonics that begin with lowercase 'k' accept a VEX prefix
6566 ++#
6567 ++#<group maps>
6568 ++# GrpTable: GrpXXX
6569 ++# reg: mnemonic [operand1[,operand2...]] [(extra1)[,(extra2)...] [| 2nd-mnemonic ...]
6570 ++# EndTable
6571 ++#
6572 ++# AVX Superscripts
6573 ++# (ev): this opcode requires EVEX prefix.
6574 ++# (evo): this opcode is changed by EVEX prefix (EVEX opcode)
6575 ++# (v): this opcode requires VEX prefix.
6576 ++# (v1): this opcode only supports 128bit VEX.
6577 ++#
6578 ++# Last Prefix Superscripts
6579 ++# - (66): the last prefix is 0x66
6580 ++# - (F3): the last prefix is 0xF3
6581 ++# - (F2): the last prefix is 0xF2
6582 ++# - (!F3) : the last prefix is not 0xF3 (including non-last prefix case)
6583 ++# - (66&F2): Both 0x66 and 0xF2 prefixes are specified.
6584 ++
6585 ++Table: one byte opcode
6586 ++Referrer:
6587 ++AVXcode:
6588 ++# 0x00 - 0x0f
6589 ++00: ADD Eb,Gb
6590 ++01: ADD Ev,Gv
6591 ++02: ADD Gb,Eb
6592 ++03: ADD Gv,Ev
6593 ++04: ADD AL,Ib
6594 ++05: ADD rAX,Iz
6595 ++06: PUSH ES (i64)
6596 ++07: POP ES (i64)
6597 ++08: OR Eb,Gb
6598 ++09: OR Ev,Gv
6599 ++0a: OR Gb,Eb
6600 ++0b: OR Gv,Ev
6601 ++0c: OR AL,Ib
6602 ++0d: OR rAX,Iz
6603 ++0e: PUSH CS (i64)
6604 ++0f: escape # 2-byte escape
6605 ++# 0x10 - 0x1f
6606 ++10: ADC Eb,Gb
6607 ++11: ADC Ev,Gv
6608 ++12: ADC Gb,Eb
6609 ++13: ADC Gv,Ev
6610 ++14: ADC AL,Ib
6611 ++15: ADC rAX,Iz
6612 ++16: PUSH SS (i64)
6613 ++17: POP SS (i64)
6614 ++18: SBB Eb,Gb
6615 ++19: SBB Ev,Gv
6616 ++1a: SBB Gb,Eb
6617 ++1b: SBB Gv,Ev
6618 ++1c: SBB AL,Ib
6619 ++1d: SBB rAX,Iz
6620 ++1e: PUSH DS (i64)
6621 ++1f: POP DS (i64)
6622 ++# 0x20 - 0x2f
6623 ++20: AND Eb,Gb
6624 ++21: AND Ev,Gv
6625 ++22: AND Gb,Eb
6626 ++23: AND Gv,Ev
6627 ++24: AND AL,Ib
6628 ++25: AND rAx,Iz
6629 ++26: SEG=ES (Prefix)
6630 ++27: DAA (i64)
6631 ++28: SUB Eb,Gb
6632 ++29: SUB Ev,Gv
6633 ++2a: SUB Gb,Eb
6634 ++2b: SUB Gv,Ev
6635 ++2c: SUB AL,Ib
6636 ++2d: SUB rAX,Iz
6637 ++2e: SEG=CS (Prefix)
6638 ++2f: DAS (i64)
6639 ++# 0x30 - 0x3f
6640 ++30: XOR Eb,Gb
6641 ++31: XOR Ev,Gv
6642 ++32: XOR Gb,Eb
6643 ++33: XOR Gv,Ev
6644 ++34: XOR AL,Ib
6645 ++35: XOR rAX,Iz
6646 ++36: SEG=SS (Prefix)
6647 ++37: AAA (i64)
6648 ++38: CMP Eb,Gb
6649 ++39: CMP Ev,Gv
6650 ++3a: CMP Gb,Eb
6651 ++3b: CMP Gv,Ev
6652 ++3c: CMP AL,Ib
6653 ++3d: CMP rAX,Iz
6654 ++3e: SEG=DS (Prefix)
6655 ++3f: AAS (i64)
6656 ++# 0x40 - 0x4f
6657 ++40: INC eAX (i64) | REX (o64)
6658 ++41: INC eCX (i64) | REX.B (o64)
6659 ++42: INC eDX (i64) | REX.X (o64)
6660 ++43: INC eBX (i64) | REX.XB (o64)
6661 ++44: INC eSP (i64) | REX.R (o64)
6662 ++45: INC eBP (i64) | REX.RB (o64)
6663 ++46: INC eSI (i64) | REX.RX (o64)
6664 ++47: INC eDI (i64) | REX.RXB (o64)
6665 ++48: DEC eAX (i64) | REX.W (o64)
6666 ++49: DEC eCX (i64) | REX.WB (o64)
6667 ++4a: DEC eDX (i64) | REX.WX (o64)
6668 ++4b: DEC eBX (i64) | REX.WXB (o64)
6669 ++4c: DEC eSP (i64) | REX.WR (o64)
6670 ++4d: DEC eBP (i64) | REX.WRB (o64)
6671 ++4e: DEC eSI (i64) | REX.WRX (o64)
6672 ++4f: DEC eDI (i64) | REX.WRXB (o64)
6673 ++# 0x50 - 0x5f
6674 ++50: PUSH rAX/r8 (d64)
6675 ++51: PUSH rCX/r9 (d64)
6676 ++52: PUSH rDX/r10 (d64)
6677 ++53: PUSH rBX/r11 (d64)
6678 ++54: PUSH rSP/r12 (d64)
6679 ++55: PUSH rBP/r13 (d64)
6680 ++56: PUSH rSI/r14 (d64)
6681 ++57: PUSH rDI/r15 (d64)
6682 ++58: POP rAX/r8 (d64)
6683 ++59: POP rCX/r9 (d64)
6684 ++5a: POP rDX/r10 (d64)
6685 ++5b: POP rBX/r11 (d64)
6686 ++5c: POP rSP/r12 (d64)
6687 ++5d: POP rBP/r13 (d64)
6688 ++5e: POP rSI/r14 (d64)
6689 ++5f: POP rDI/r15 (d64)
6690 ++# 0x60 - 0x6f
6691 ++60: PUSHA/PUSHAD (i64)
6692 ++61: POPA/POPAD (i64)
6693 ++62: BOUND Gv,Ma (i64) | EVEX (Prefix)
6694 ++63: ARPL Ew,Gw (i64) | MOVSXD Gv,Ev (o64)
6695 ++64: SEG=FS (Prefix)
6696 ++65: SEG=GS (Prefix)
6697 ++66: Operand-Size (Prefix)
6698 ++67: Address-Size (Prefix)
6699 ++68: PUSH Iz (d64)
6700 ++69: IMUL Gv,Ev,Iz
6701 ++6a: PUSH Ib (d64)
6702 ++6b: IMUL Gv,Ev,Ib
6703 ++6c: INS/INSB Yb,DX
6704 ++6d: INS/INSW/INSD Yz,DX
6705 ++6e: OUTS/OUTSB DX,Xb
6706 ++6f: OUTS/OUTSW/OUTSD DX,Xz
6707 ++# 0x70 - 0x7f
6708 ++70: JO Jb
6709 ++71: JNO Jb
6710 ++72: JB/JNAE/JC Jb
6711 ++73: JNB/JAE/JNC Jb
6712 ++74: JZ/JE Jb
6713 ++75: JNZ/JNE Jb
6714 ++76: JBE/JNA Jb
6715 ++77: JNBE/JA Jb
6716 ++78: JS Jb
6717 ++79: JNS Jb
6718 ++7a: JP/JPE Jb
6719 ++7b: JNP/JPO Jb
6720 ++7c: JL/JNGE Jb
6721 ++7d: JNL/JGE Jb
6722 ++7e: JLE/JNG Jb
6723 ++7f: JNLE/JG Jb
6724 ++# 0x80 - 0x8f
6725 ++80: Grp1 Eb,Ib (1A)
6726 ++81: Grp1 Ev,Iz (1A)
6727 ++82: Grp1 Eb,Ib (1A),(i64)
6728 ++83: Grp1 Ev,Ib (1A)
6729 ++84: TEST Eb,Gb
6730 ++85: TEST Ev,Gv
6731 ++86: XCHG Eb,Gb
6732 ++87: XCHG Ev,Gv
6733 ++88: MOV Eb,Gb
6734 ++89: MOV Ev,Gv
6735 ++8a: MOV Gb,Eb
6736 ++8b: MOV Gv,Ev
6737 ++8c: MOV Ev,Sw
6738 ++8d: LEA Gv,M
6739 ++8e: MOV Sw,Ew
6740 ++8f: Grp1A (1A) | POP Ev (d64)
6741 ++# 0x90 - 0x9f
6742 ++90: NOP | PAUSE (F3) | XCHG r8,rAX
6743 ++91: XCHG rCX/r9,rAX
6744 ++92: XCHG rDX/r10,rAX
6745 ++93: XCHG rBX/r11,rAX
6746 ++94: XCHG rSP/r12,rAX
6747 ++95: XCHG rBP/r13,rAX
6748 ++96: XCHG rSI/r14,rAX
6749 ++97: XCHG rDI/r15,rAX
6750 ++98: CBW/CWDE/CDQE
6751 ++99: CWD/CDQ/CQO
6752 ++9a: CALLF Ap (i64)
6753 ++9b: FWAIT/WAIT
6754 ++9c: PUSHF/D/Q Fv (d64)
6755 ++9d: POPF/D/Q Fv (d64)
6756 ++9e: SAHF
6757 ++9f: LAHF
6758 ++# 0xa0 - 0xaf
6759 ++a0: MOV AL,Ob
6760 ++a1: MOV rAX,Ov
6761 ++a2: MOV Ob,AL
6762 ++a3: MOV Ov,rAX
6763 ++a4: MOVS/B Yb,Xb
6764 ++a5: MOVS/W/D/Q Yv,Xv
6765 ++a6: CMPS/B Xb,Yb
6766 ++a7: CMPS/W/D Xv,Yv
6767 ++a8: TEST AL,Ib
6768 ++a9: TEST rAX,Iz
6769 ++aa: STOS/B Yb,AL
6770 ++ab: STOS/W/D/Q Yv,rAX
6771 ++ac: LODS/B AL,Xb
6772 ++ad: LODS/W/D/Q rAX,Xv
6773 ++ae: SCAS/B AL,Yb
6774 ++# Note: The May 2011 Intel manual shows Xv for the second parameter of the
6775 ++# next instruction but Yv is correct
6776 ++af: SCAS/W/D/Q rAX,Yv
6777 ++# 0xb0 - 0xbf
6778 ++b0: MOV AL/R8L,Ib
6779 ++b1: MOV CL/R9L,Ib
6780 ++b2: MOV DL/R10L,Ib
6781 ++b3: MOV BL/R11L,Ib
6782 ++b4: MOV AH/R12L,Ib
6783 ++b5: MOV CH/R13L,Ib
6784 ++b6: MOV DH/R14L,Ib
6785 ++b7: MOV BH/R15L,Ib
6786 ++b8: MOV rAX/r8,Iv
6787 ++b9: MOV rCX/r9,Iv
6788 ++ba: MOV rDX/r10,Iv
6789 ++bb: MOV rBX/r11,Iv
6790 ++bc: MOV rSP/r12,Iv
6791 ++bd: MOV rBP/r13,Iv
6792 ++be: MOV rSI/r14,Iv
6793 ++bf: MOV rDI/r15,Iv
6794 ++# 0xc0 - 0xcf
6795 ++c0: Grp2 Eb,Ib (1A)
6796 ++c1: Grp2 Ev,Ib (1A)
6797 ++c2: RETN Iw (f64)
6798 ++c3: RETN
6799 ++c4: LES Gz,Mp (i64) | VEX+2byte (Prefix)
6800 ++c5: LDS Gz,Mp (i64) | VEX+1byte (Prefix)
6801 ++c6: Grp11A Eb,Ib (1A)
6802 ++c7: Grp11B Ev,Iz (1A)
6803 ++c8: ENTER Iw,Ib
6804 ++c9: LEAVE (d64)
6805 ++ca: RETF Iw
6806 ++cb: RETF
6807 ++cc: INT3
6808 ++cd: INT Ib
6809 ++ce: INTO (i64)
6810 ++cf: IRET/D/Q
6811 ++# 0xd0 - 0xdf
6812 ++d0: Grp2 Eb,1 (1A)
6813 ++d1: Grp2 Ev,1 (1A)
6814 ++d2: Grp2 Eb,CL (1A)
6815 ++d3: Grp2 Ev,CL (1A)
6816 ++d4: AAM Ib (i64)
6817 ++d5: AAD Ib (i64)
6818 ++d6:
6819 ++d7: XLAT/XLATB
6820 ++d8: ESC
6821 ++d9: ESC
6822 ++da: ESC
6823 ++db: ESC
6824 ++dc: ESC
6825 ++dd: ESC
6826 ++de: ESC
6827 ++df: ESC
6828 ++# 0xe0 - 0xef
6829 ++# Note: "forced64" is Intel CPU behavior: they ignore 0x66 prefix
6830 ++# in 64-bit mode. AMD CPUs accept 0x66 prefix, it causes RIP truncation
6831 ++# to 16 bits. In 32-bit mode, 0x66 is accepted by both Intel and AMD.
6832 ++e0: LOOPNE/LOOPNZ Jb (f64)
6833 ++e1: LOOPE/LOOPZ Jb (f64)
6834 ++e2: LOOP Jb (f64)
6835 ++e3: JrCXZ Jb (f64)
6836 ++e4: IN AL,Ib
6837 ++e5: IN eAX,Ib
6838 ++e6: OUT Ib,AL
6839 ++e7: OUT Ib,eAX
6840 ++# With 0x66 prefix in 64-bit mode, for AMD CPUs immediate offset
6841 ++# in "near" jumps and calls is 16-bit. For CALL,
6842 ++# push of return address is 16-bit wide, RSP is decremented by 2
6843 ++# but is not truncated to 16 bits, unlike RIP.
6844 ++e8: CALL Jz (f64)
6845 ++e9: JMP-near Jz (f64)
6846 ++ea: JMP-far Ap (i64)
6847 ++eb: JMP-short Jb (f64)
6848 ++ec: IN AL,DX
6849 ++ed: IN eAX,DX
6850 ++ee: OUT DX,AL
6851 ++ef: OUT DX,eAX
6852 ++# 0xf0 - 0xff
6853 ++f0: LOCK (Prefix)
6854 ++f1:
6855 ++f2: REPNE (Prefix) | XACQUIRE (Prefix)
6856 ++f3: REP/REPE (Prefix) | XRELEASE (Prefix)
6857 ++f4: HLT
6858 ++f5: CMC
6859 ++f6: Grp3_1 Eb (1A)
6860 ++f7: Grp3_2 Ev (1A)
6861 ++f8: CLC
6862 ++f9: STC
6863 ++fa: CLI
6864 ++fb: STI
6865 ++fc: CLD
6866 ++fd: STD
6867 ++fe: Grp4 (1A)
6868 ++ff: Grp5 (1A)
6869 ++EndTable
6870 ++
6871 ++Table: 2-byte opcode (0x0f)
6872 ++Referrer: 2-byte escape
6873 ++AVXcode: 1
6874 ++# 0x0f 0x00-0x0f
6875 ++00: Grp6 (1A)
6876 ++01: Grp7 (1A)
6877 ++02: LAR Gv,Ew
6878 ++03: LSL Gv,Ew
6879 ++04:
6880 ++05: SYSCALL (o64)
6881 ++06: CLTS
6882 ++07: SYSRET (o64)
6883 ++08: INVD
6884 ++09: WBINVD
6885 ++0a:
6886 ++0b: UD2 (1B)
6887 ++0c:
6888 ++# AMD's prefetch group. Intel supports prefetchw(/1) only.
6889 ++0d: GrpP
6890 ++0e: FEMMS
6891 ++# 3DNow! uses the last imm byte as opcode extension.
6892 ++0f: 3DNow! Pq,Qq,Ib
6893 ++# 0x0f 0x10-0x1f
6894 ++# NOTE: According to Intel SDM opcode map, vmovups and vmovupd has no operands
6895 ++# but it actually has operands. And also, vmovss and vmovsd only accept 128bit.
6896 ++# MOVSS/MOVSD has too many forms(3) on SDM. This map just shows a typical form.
6897 ++# Many AVX instructions lack v1 superscript, according to Intel AVX-Prgramming
6898 ++# Reference A.1
6899 ++10: vmovups Vps,Wps | vmovupd Vpd,Wpd (66) | vmovss Vx,Hx,Wss (F3),(v1) | vmovsd Vx,Hx,Wsd (F2),(v1)
6900 ++11: vmovups Wps,Vps | vmovupd Wpd,Vpd (66) | vmovss Wss,Hx,Vss (F3),(v1) | vmovsd Wsd,Hx,Vsd (F2),(v1)
6901 ++12: vmovlps Vq,Hq,Mq (v1) | vmovhlps Vq,Hq,Uq (v1) | vmovlpd Vq,Hq,Mq (66),(v1) | vmovsldup Vx,Wx (F3) | vmovddup Vx,Wx (F2)
6902 ++13: vmovlps Mq,Vq (v1) | vmovlpd Mq,Vq (66),(v1)
6903 ++14: vunpcklps Vx,Hx,Wx | vunpcklpd Vx,Hx,Wx (66)
6904 ++15: vunpckhps Vx,Hx,Wx | vunpckhpd Vx,Hx,Wx (66)
6905 ++16: vmovhps Vdq,Hq,Mq (v1) | vmovlhps Vdq,Hq,Uq (v1) | vmovhpd Vdq,Hq,Mq (66),(v1) | vmovshdup Vx,Wx (F3)
6906 ++17: vmovhps Mq,Vq (v1) | vmovhpd Mq,Vq (66),(v1)
6907 ++18: Grp16 (1A)
6908 ++19:
6909 ++# Intel SDM opcode map does not list MPX instructions. For now using Gv for
6910 ++# bnd registers and Ev for everything else is OK because the instruction
6911 ++# decoder does not use the information except as an indication that there is
6912 ++# a ModR/M byte.
6913 ++1a: BNDCL Gv,Ev (F3) | BNDCU Gv,Ev (F2) | BNDMOV Gv,Ev (66) | BNDLDX Gv,Ev
6914 ++1b: BNDCN Gv,Ev (F2) | BNDMOV Ev,Gv (66) | BNDMK Gv,Ev (F3) | BNDSTX Ev,Gv
6915 ++1c:
6916 ++1d:
6917 ++1e:
6918 ++1f: NOP Ev
6919 ++# 0x0f 0x20-0x2f
6920 ++20: MOV Rd,Cd
6921 ++21: MOV Rd,Dd
6922 ++22: MOV Cd,Rd
6923 ++23: MOV Dd,Rd
6924 ++24:
6925 ++25:
6926 ++26:
6927 ++27:
6928 ++28: vmovaps Vps,Wps | vmovapd Vpd,Wpd (66)
6929 ++29: vmovaps Wps,Vps | vmovapd Wpd,Vpd (66)
6930 ++2a: cvtpi2ps Vps,Qpi | cvtpi2pd Vpd,Qpi (66) | vcvtsi2ss Vss,Hss,Ey (F3),(v1) | vcvtsi2sd Vsd,Hsd,Ey (F2),(v1)
6931 ++2b: vmovntps Mps,Vps | vmovntpd Mpd,Vpd (66)
6932 ++2c: cvttps2pi Ppi,Wps | cvttpd2pi Ppi,Wpd (66) | vcvttss2si Gy,Wss (F3),(v1) | vcvttsd2si Gy,Wsd (F2),(v1)
6933 ++2d: cvtps2pi Ppi,Wps | cvtpd2pi Qpi,Wpd (66) | vcvtss2si Gy,Wss (F3),(v1) | vcvtsd2si Gy,Wsd (F2),(v1)
6934 ++2e: vucomiss Vss,Wss (v1) | vucomisd Vsd,Wsd (66),(v1)
6935 ++2f: vcomiss Vss,Wss (v1) | vcomisd Vsd,Wsd (66),(v1)
6936 ++# 0x0f 0x30-0x3f
6937 ++30: WRMSR
6938 ++31: RDTSC
6939 ++32: RDMSR
6940 ++33: RDPMC
6941 ++34: SYSENTER
6942 ++35: SYSEXIT
6943 ++36:
6944 ++37: GETSEC
6945 ++38: escape # 3-byte escape 1
6946 ++39:
6947 ++3a: escape # 3-byte escape 2
6948 ++3b:
6949 ++3c:
6950 ++3d:
6951 ++3e:
6952 ++3f:
6953 ++# 0x0f 0x40-0x4f
6954 ++40: CMOVO Gv,Ev
6955 ++41: CMOVNO Gv,Ev | kandw/q Vk,Hk,Uk | kandb/d Vk,Hk,Uk (66)
6956 ++42: CMOVB/C/NAE Gv,Ev | kandnw/q Vk,Hk,Uk | kandnb/d Vk,Hk,Uk (66)
6957 ++43: CMOVAE/NB/NC Gv,Ev
6958 ++44: CMOVE/Z Gv,Ev | knotw/q Vk,Uk | knotb/d Vk,Uk (66)
6959 ++45: CMOVNE/NZ Gv,Ev | korw/q Vk,Hk,Uk | korb/d Vk,Hk,Uk (66)
6960 ++46: CMOVBE/NA Gv,Ev | kxnorw/q Vk,Hk,Uk | kxnorb/d Vk,Hk,Uk (66)
6961 ++47: CMOVA/NBE Gv,Ev | kxorw/q Vk,Hk,Uk | kxorb/d Vk,Hk,Uk (66)
6962 ++48: CMOVS Gv,Ev
6963 ++49: CMOVNS Gv,Ev
6964 ++4a: CMOVP/PE Gv,Ev | kaddw/q Vk,Hk,Uk | kaddb/d Vk,Hk,Uk (66)
6965 ++4b: CMOVNP/PO Gv,Ev | kunpckbw Vk,Hk,Uk (66) | kunpckwd/dq Vk,Hk,Uk
6966 ++4c: CMOVL/NGE Gv,Ev
6967 ++4d: CMOVNL/GE Gv,Ev
6968 ++4e: CMOVLE/NG Gv,Ev
6969 ++4f: CMOVNLE/G Gv,Ev
6970 ++# 0x0f 0x50-0x5f
6971 ++50: vmovmskps Gy,Ups | vmovmskpd Gy,Upd (66)
6972 ++51: vsqrtps Vps,Wps | vsqrtpd Vpd,Wpd (66) | vsqrtss Vss,Hss,Wss (F3),(v1) | vsqrtsd Vsd,Hsd,Wsd (F2),(v1)
6973 ++52: vrsqrtps Vps,Wps | vrsqrtss Vss,Hss,Wss (F3),(v1)
6974 ++53: vrcpps Vps,Wps | vrcpss Vss,Hss,Wss (F3),(v1)
6975 ++54: vandps Vps,Hps,Wps | vandpd Vpd,Hpd,Wpd (66)
6976 ++55: vandnps Vps,Hps,Wps | vandnpd Vpd,Hpd,Wpd (66)
6977 ++56: vorps Vps,Hps,Wps | vorpd Vpd,Hpd,Wpd (66)
6978 ++57: vxorps Vps,Hps,Wps | vxorpd Vpd,Hpd,Wpd (66)
6979 ++58: vaddps Vps,Hps,Wps | vaddpd Vpd,Hpd,Wpd (66) | vaddss Vss,Hss,Wss (F3),(v1) | vaddsd Vsd,Hsd,Wsd (F2),(v1)
6980 ++59: vmulps Vps,Hps,Wps | vmulpd Vpd,Hpd,Wpd (66) | vmulss Vss,Hss,Wss (F3),(v1) | vmulsd Vsd,Hsd,Wsd (F2),(v1)
6981 ++5a: vcvtps2pd Vpd,Wps | vcvtpd2ps Vps,Wpd (66) | vcvtss2sd Vsd,Hx,Wss (F3),(v1) | vcvtsd2ss Vss,Hx,Wsd (F2),(v1)
6982 ++5b: vcvtdq2ps Vps,Wdq | vcvtqq2ps Vps,Wqq (evo) | vcvtps2dq Vdq,Wps (66) | vcvttps2dq Vdq,Wps (F3)
6983 ++5c: vsubps Vps,Hps,Wps | vsubpd Vpd,Hpd,Wpd (66) | vsubss Vss,Hss,Wss (F3),(v1) | vsubsd Vsd,Hsd,Wsd (F2),(v1)
6984 ++5d: vminps Vps,Hps,Wps | vminpd Vpd,Hpd,Wpd (66) | vminss Vss,Hss,Wss (F3),(v1) | vminsd Vsd,Hsd,Wsd (F2),(v1)
6985 ++5e: vdivps Vps,Hps,Wps | vdivpd Vpd,Hpd,Wpd (66) | vdivss Vss,Hss,Wss (F3),(v1) | vdivsd Vsd,Hsd,Wsd (F2),(v1)
6986 ++5f: vmaxps Vps,Hps,Wps | vmaxpd Vpd,Hpd,Wpd (66) | vmaxss Vss,Hss,Wss (F3),(v1) | vmaxsd Vsd,Hsd,Wsd (F2),(v1)
6987 ++# 0x0f 0x60-0x6f
6988 ++60: punpcklbw Pq,Qd | vpunpcklbw Vx,Hx,Wx (66),(v1)
6989 ++61: punpcklwd Pq,Qd | vpunpcklwd Vx,Hx,Wx (66),(v1)
6990 ++62: punpckldq Pq,Qd | vpunpckldq Vx,Hx,Wx (66),(v1)
6991 ++63: packsswb Pq,Qq | vpacksswb Vx,Hx,Wx (66),(v1)
6992 ++64: pcmpgtb Pq,Qq | vpcmpgtb Vx,Hx,Wx (66),(v1)
6993 ++65: pcmpgtw Pq,Qq | vpcmpgtw Vx,Hx,Wx (66),(v1)
6994 ++66: pcmpgtd Pq,Qq | vpcmpgtd Vx,Hx,Wx (66),(v1)
6995 ++67: packuswb Pq,Qq | vpackuswb Vx,Hx,Wx (66),(v1)
6996 ++68: punpckhbw Pq,Qd | vpunpckhbw Vx,Hx,Wx (66),(v1)
6997 ++69: punpckhwd Pq,Qd | vpunpckhwd Vx,Hx,Wx (66),(v1)
6998 ++6a: punpckhdq Pq,Qd | vpunpckhdq Vx,Hx,Wx (66),(v1)
6999 ++6b: packssdw Pq,Qd | vpackssdw Vx,Hx,Wx (66),(v1)
7000 ++6c: vpunpcklqdq Vx,Hx,Wx (66),(v1)
7001 ++6d: vpunpckhqdq Vx,Hx,Wx (66),(v1)
7002 ++6e: movd/q Pd,Ey | vmovd/q Vy,Ey (66),(v1)
7003 ++6f: movq Pq,Qq | vmovdqa Vx,Wx (66) | vmovdqa32/64 Vx,Wx (66),(evo) | vmovdqu Vx,Wx (F3) | vmovdqu32/64 Vx,Wx (F3),(evo) | vmovdqu8/16 Vx,Wx (F2),(ev)
7004 ++# 0x0f 0x70-0x7f
7005 ++70: pshufw Pq,Qq,Ib | vpshufd Vx,Wx,Ib (66),(v1) | vpshufhw Vx,Wx,Ib (F3),(v1) | vpshuflw Vx,Wx,Ib (F2),(v1)
7006 ++71: Grp12 (1A)
7007 ++72: Grp13 (1A)
7008 ++73: Grp14 (1A)
7009 ++74: pcmpeqb Pq,Qq | vpcmpeqb Vx,Hx,Wx (66),(v1)
7010 ++75: pcmpeqw Pq,Qq | vpcmpeqw Vx,Hx,Wx (66),(v1)
7011 ++76: pcmpeqd Pq,Qq | vpcmpeqd Vx,Hx,Wx (66),(v1)
7012 ++# Note: Remove (v), because vzeroall and vzeroupper becomes emms without VEX.
7013 ++77: emms | vzeroupper | vzeroall
7014 ++78: VMREAD Ey,Gy | vcvttps2udq/pd2udq Vx,Wpd (evo) | vcvttsd2usi Gv,Wx (F2),(ev) | vcvttss2usi Gv,Wx (F3),(ev) | vcvttps2uqq/pd2uqq Vx,Wx (66),(ev)
7015 ++79: VMWRITE Gy,Ey | vcvtps2udq/pd2udq Vx,Wpd (evo) | vcvtsd2usi Gv,Wx (F2),(ev) | vcvtss2usi Gv,Wx (F3),(ev) | vcvtps2uqq/pd2uqq Vx,Wx (66),(ev)
7016 ++7a: vcvtudq2pd/uqq2pd Vpd,Wx (F3),(ev) | vcvtudq2ps/uqq2ps Vpd,Wx (F2),(ev) | vcvttps2qq/pd2qq Vx,Wx (66),(ev)
7017 ++7b: vcvtusi2sd Vpd,Hpd,Ev (F2),(ev) | vcvtusi2ss Vps,Hps,Ev (F3),(ev) | vcvtps2qq/pd2qq Vx,Wx (66),(ev)
7018 ++7c: vhaddpd Vpd,Hpd,Wpd (66) | vhaddps Vps,Hps,Wps (F2)
7019 ++7d: vhsubpd Vpd,Hpd,Wpd (66) | vhsubps Vps,Hps,Wps (F2)
7020 ++7e: movd/q Ey,Pd | vmovd/q Ey,Vy (66),(v1) | vmovq Vq,Wq (F3),(v1)
7021 ++7f: movq Qq,Pq | vmovdqa Wx,Vx (66) | vmovdqa32/64 Wx,Vx (66),(evo) | vmovdqu Wx,Vx (F3) | vmovdqu32/64 Wx,Vx (F3),(evo) | vmovdqu8/16 Wx,Vx (F2),(ev)
7022 ++# 0x0f 0x80-0x8f
7023 ++# Note: "forced64" is Intel CPU behavior (see comment about CALL insn).
7024 ++80: JO Jz (f64)
7025 ++81: JNO Jz (f64)
7026 ++82: JB/JC/JNAE Jz (f64)
7027 ++83: JAE/JNB/JNC Jz (f64)
7028 ++84: JE/JZ Jz (f64)
7029 ++85: JNE/JNZ Jz (f64)
7030 ++86: JBE/JNA Jz (f64)
7031 ++87: JA/JNBE Jz (f64)
7032 ++88: JS Jz (f64)
7033 ++89: JNS Jz (f64)
7034 ++8a: JP/JPE Jz (f64)
7035 ++8b: JNP/JPO Jz (f64)
7036 ++8c: JL/JNGE Jz (f64)
7037 ++8d: JNL/JGE Jz (f64)
7038 ++8e: JLE/JNG Jz (f64)
7039 ++8f: JNLE/JG Jz (f64)
7040 ++# 0x0f 0x90-0x9f
7041 ++90: SETO Eb | kmovw/q Vk,Wk | kmovb/d Vk,Wk (66)
7042 ++91: SETNO Eb | kmovw/q Mv,Vk | kmovb/d Mv,Vk (66)
7043 ++92: SETB/C/NAE Eb | kmovw Vk,Rv | kmovb Vk,Rv (66) | kmovq/d Vk,Rv (F2)
7044 ++93: SETAE/NB/NC Eb | kmovw Gv,Uk | kmovb Gv,Uk (66) | kmovq/d Gv,Uk (F2)
7045 ++94: SETE/Z Eb
7046 ++95: SETNE/NZ Eb
7047 ++96: SETBE/NA Eb
7048 ++97: SETA/NBE Eb
7049 ++98: SETS Eb | kortestw/q Vk,Uk | kortestb/d Vk,Uk (66)
7050 ++99: SETNS Eb | ktestw/q Vk,Uk | ktestb/d Vk,Uk (66)
7051 ++9a: SETP/PE Eb
7052 ++9b: SETNP/PO Eb
7053 ++9c: SETL/NGE Eb
7054 ++9d: SETNL/GE Eb
7055 ++9e: SETLE/NG Eb
7056 ++9f: SETNLE/G Eb
7057 ++# 0x0f 0xa0-0xaf
7058 ++a0: PUSH FS (d64)
7059 ++a1: POP FS (d64)
7060 ++a2: CPUID
7061 ++a3: BT Ev,Gv
7062 ++a4: SHLD Ev,Gv,Ib
7063 ++a5: SHLD Ev,Gv,CL
7064 ++a6: GrpPDLK
7065 ++a7: GrpRNG
7066 ++a8: PUSH GS (d64)
7067 ++a9: POP GS (d64)
7068 ++aa: RSM
7069 ++ab: BTS Ev,Gv
7070 ++ac: SHRD Ev,Gv,Ib
7071 ++ad: SHRD Ev,Gv,CL
7072 ++ae: Grp15 (1A),(1C)
7073 ++af: IMUL Gv,Ev
7074 ++# 0x0f 0xb0-0xbf
7075 ++b0: CMPXCHG Eb,Gb
7076 ++b1: CMPXCHG Ev,Gv
7077 ++b2: LSS Gv,Mp
7078 ++b3: BTR Ev,Gv
7079 ++b4: LFS Gv,Mp
7080 ++b5: LGS Gv,Mp
7081 ++b6: MOVZX Gv,Eb
7082 ++b7: MOVZX Gv,Ew
7083 ++b8: JMPE (!F3) | POPCNT Gv,Ev (F3)
7084 ++b9: Grp10 (1A)
7085 ++ba: Grp8 Ev,Ib (1A)
7086 ++bb: BTC Ev,Gv
7087 ++bc: BSF Gv,Ev (!F3) | TZCNT Gv,Ev (F3)
7088 ++bd: BSR Gv,Ev (!F3) | LZCNT Gv,Ev (F3)
7089 ++be: MOVSX Gv,Eb
7090 ++bf: MOVSX Gv,Ew
7091 ++# 0x0f 0xc0-0xcf
7092 ++c0: XADD Eb,Gb
7093 ++c1: XADD Ev,Gv
7094 ++c2: vcmpps Vps,Hps,Wps,Ib | vcmppd Vpd,Hpd,Wpd,Ib (66) | vcmpss Vss,Hss,Wss,Ib (F3),(v1) | vcmpsd Vsd,Hsd,Wsd,Ib (F2),(v1)
7095 ++c3: movnti My,Gy
7096 ++c4: pinsrw Pq,Ry/Mw,Ib | vpinsrw Vdq,Hdq,Ry/Mw,Ib (66),(v1)
7097 ++c5: pextrw Gd,Nq,Ib | vpextrw Gd,Udq,Ib (66),(v1)
7098 ++c6: vshufps Vps,Hps,Wps,Ib | vshufpd Vpd,Hpd,Wpd,Ib (66)
7099 ++c7: Grp9 (1A)
7100 ++c8: BSWAP RAX/EAX/R8/R8D
7101 ++c9: BSWAP RCX/ECX/R9/R9D
7102 ++ca: BSWAP RDX/EDX/R10/R10D
7103 ++cb: BSWAP RBX/EBX/R11/R11D
7104 ++cc: BSWAP RSP/ESP/R12/R12D
7105 ++cd: BSWAP RBP/EBP/R13/R13D
7106 ++ce: BSWAP RSI/ESI/R14/R14D
7107 ++cf: BSWAP RDI/EDI/R15/R15D
7108 ++# 0x0f 0xd0-0xdf
7109 ++d0: vaddsubpd Vpd,Hpd,Wpd (66) | vaddsubps Vps,Hps,Wps (F2)
7110 ++d1: psrlw Pq,Qq | vpsrlw Vx,Hx,Wx (66),(v1)
7111 ++d2: psrld Pq,Qq | vpsrld Vx,Hx,Wx (66),(v1)
7112 ++d3: psrlq Pq,Qq | vpsrlq Vx,Hx,Wx (66),(v1)
7113 ++d4: paddq Pq,Qq | vpaddq Vx,Hx,Wx (66),(v1)
7114 ++d5: pmullw Pq,Qq | vpmullw Vx,Hx,Wx (66),(v1)
7115 ++d6: vmovq Wq,Vq (66),(v1) | movq2dq Vdq,Nq (F3) | movdq2q Pq,Uq (F2)
7116 ++d7: pmovmskb Gd,Nq | vpmovmskb Gd,Ux (66),(v1)
7117 ++d8: psubusb Pq,Qq | vpsubusb Vx,Hx,Wx (66),(v1)
7118 ++d9: psubusw Pq,Qq | vpsubusw Vx,Hx,Wx (66),(v1)
7119 ++da: pminub Pq,Qq | vpminub Vx,Hx,Wx (66),(v1)
7120 ++db: pand Pq,Qq | vpand Vx,Hx,Wx (66),(v1) | vpandd/q Vx,Hx,Wx (66),(evo)
7121 ++dc: paddusb Pq,Qq | vpaddusb Vx,Hx,Wx (66),(v1)
7122 ++dd: paddusw Pq,Qq | vpaddusw Vx,Hx,Wx (66),(v1)
7123 ++de: pmaxub Pq,Qq | vpmaxub Vx,Hx,Wx (66),(v1)
7124 ++df: pandn Pq,Qq | vpandn Vx,Hx,Wx (66),(v1) | vpandnd/q Vx,Hx,Wx (66),(evo)
7125 ++# 0x0f 0xe0-0xef
7126 ++e0: pavgb Pq,Qq | vpavgb Vx,Hx,Wx (66),(v1)
7127 ++e1: psraw Pq,Qq | vpsraw Vx,Hx,Wx (66),(v1)
7128 ++e2: psrad Pq,Qq | vpsrad Vx,Hx,Wx (66),(v1)
7129 ++e3: pavgw Pq,Qq | vpavgw Vx,Hx,Wx (66),(v1)
7130 ++e4: pmulhuw Pq,Qq | vpmulhuw Vx,Hx,Wx (66),(v1)
7131 ++e5: pmulhw Pq,Qq | vpmulhw Vx,Hx,Wx (66),(v1)
7132 ++e6: vcvttpd2dq Vx,Wpd (66) | vcvtdq2pd Vx,Wdq (F3) | vcvtdq2pd/qq2pd Vx,Wdq (F3),(evo) | vcvtpd2dq Vx,Wpd (F2)
7133 ++e7: movntq Mq,Pq | vmovntdq Mx,Vx (66)
7134 ++e8: psubsb Pq,Qq | vpsubsb Vx,Hx,Wx (66),(v1)
7135 ++e9: psubsw Pq,Qq | vpsubsw Vx,Hx,Wx (66),(v1)
7136 ++ea: pminsw Pq,Qq | vpminsw Vx,Hx,Wx (66),(v1)
7137 ++eb: por Pq,Qq | vpor Vx,Hx,Wx (66),(v1) | vpord/q Vx,Hx,Wx (66),(evo)
7138 ++ec: paddsb Pq,Qq | vpaddsb Vx,Hx,Wx (66),(v1)
7139 ++ed: paddsw Pq,Qq | vpaddsw Vx,Hx,Wx (66),(v1)
7140 ++ee: pmaxsw Pq,Qq | vpmaxsw Vx,Hx,Wx (66),(v1)
7141 ++ef: pxor Pq,Qq | vpxor Vx,Hx,Wx (66),(v1) | vpxord/q Vx,Hx,Wx (66),(evo)
7142 ++# 0x0f 0xf0-0xff
7143 ++f0: vlddqu Vx,Mx (F2)
7144 ++f1: psllw Pq,Qq | vpsllw Vx,Hx,Wx (66),(v1)
7145 ++f2: pslld Pq,Qq | vpslld Vx,Hx,Wx (66),(v1)
7146 ++f3: psllq Pq,Qq | vpsllq Vx,Hx,Wx (66),(v1)
7147 ++f4: pmuludq Pq,Qq | vpmuludq Vx,Hx,Wx (66),(v1)
7148 ++f5: pmaddwd Pq,Qq | vpmaddwd Vx,Hx,Wx (66),(v1)
7149 ++f6: psadbw Pq,Qq | vpsadbw Vx,Hx,Wx (66),(v1)
7150 ++f7: maskmovq Pq,Nq | vmaskmovdqu Vx,Ux (66),(v1)
7151 ++f8: psubb Pq,Qq | vpsubb Vx,Hx,Wx (66),(v1)
7152 ++f9: psubw Pq,Qq | vpsubw Vx,Hx,Wx (66),(v1)
7153 ++fa: psubd Pq,Qq | vpsubd Vx,Hx,Wx (66),(v1)
7154 ++fb: psubq Pq,Qq | vpsubq Vx,Hx,Wx (66),(v1)
7155 ++fc: paddb Pq,Qq | vpaddb Vx,Hx,Wx (66),(v1)
7156 ++fd: paddw Pq,Qq | vpaddw Vx,Hx,Wx (66),(v1)
7157 ++fe: paddd Pq,Qq | vpaddd Vx,Hx,Wx (66),(v1)
7158 ++ff:
7159 ++EndTable
7160 ++
7161 ++Table: 3-byte opcode 1 (0x0f 0x38)
7162 ++Referrer: 3-byte escape 1
7163 ++AVXcode: 2
7164 ++# 0x0f 0x38 0x00-0x0f
7165 ++00: pshufb Pq,Qq | vpshufb Vx,Hx,Wx (66),(v1)
7166 ++01: phaddw Pq,Qq | vphaddw Vx,Hx,Wx (66),(v1)
7167 ++02: phaddd Pq,Qq | vphaddd Vx,Hx,Wx (66),(v1)
7168 ++03: phaddsw Pq,Qq | vphaddsw Vx,Hx,Wx (66),(v1)
7169 ++04: pmaddubsw Pq,Qq | vpmaddubsw Vx,Hx,Wx (66),(v1)
7170 ++05: phsubw Pq,Qq | vphsubw Vx,Hx,Wx (66),(v1)
7171 ++06: phsubd Pq,Qq | vphsubd Vx,Hx,Wx (66),(v1)
7172 ++07: phsubsw Pq,Qq | vphsubsw Vx,Hx,Wx (66),(v1)
7173 ++08: psignb Pq,Qq | vpsignb Vx,Hx,Wx (66),(v1)
7174 ++09: psignw Pq,Qq | vpsignw Vx,Hx,Wx (66),(v1)
7175 ++0a: psignd Pq,Qq | vpsignd Vx,Hx,Wx (66),(v1)
7176 ++0b: pmulhrsw Pq,Qq | vpmulhrsw Vx,Hx,Wx (66),(v1)
7177 ++0c: vpermilps Vx,Hx,Wx (66),(v)
7178 ++0d: vpermilpd Vx,Hx,Wx (66),(v)
7179 ++0e: vtestps Vx,Wx (66),(v)
7180 ++0f: vtestpd Vx,Wx (66),(v)
7181 ++# 0x0f 0x38 0x10-0x1f
7182 ++10: pblendvb Vdq,Wdq (66) | vpsrlvw Vx,Hx,Wx (66),(evo) | vpmovuswb Wx,Vx (F3),(ev)
7183 ++11: vpmovusdb Wx,Vd (F3),(ev) | vpsravw Vx,Hx,Wx (66),(ev)
7184 ++12: vpmovusqb Wx,Vq (F3),(ev) | vpsllvw Vx,Hx,Wx (66),(ev)
7185 ++13: vcvtph2ps Vx,Wx (66),(v) | vpmovusdw Wx,Vd (F3),(ev)
7186 ++14: blendvps Vdq,Wdq (66) | vpmovusqw Wx,Vq (F3),(ev) | vprorvd/q Vx,Hx,Wx (66),(evo)
7187 ++15: blendvpd Vdq,Wdq (66) | vpmovusqd Wx,Vq (F3),(ev) | vprolvd/q Vx,Hx,Wx (66),(evo)
7188 ++16: vpermps Vqq,Hqq,Wqq (66),(v) | vpermps/d Vqq,Hqq,Wqq (66),(evo)
7189 ++17: vptest Vx,Wx (66)
7190 ++18: vbroadcastss Vx,Wd (66),(v)
7191 ++19: vbroadcastsd Vqq,Wq (66),(v) | vbroadcastf32x2 Vqq,Wq (66),(evo)
7192 ++1a: vbroadcastf128 Vqq,Mdq (66),(v) | vbroadcastf32x4/64x2 Vqq,Wq (66),(evo)
7193 ++1b: vbroadcastf32x8/64x4 Vqq,Mdq (66),(ev)
7194 ++1c: pabsb Pq,Qq | vpabsb Vx,Wx (66),(v1)
7195 ++1d: pabsw Pq,Qq | vpabsw Vx,Wx (66),(v1)
7196 ++1e: pabsd Pq,Qq | vpabsd Vx,Wx (66),(v1)
7197 ++1f: vpabsq Vx,Wx (66),(ev)
7198 ++# 0x0f 0x38 0x20-0x2f
7199 ++20: vpmovsxbw Vx,Ux/Mq (66),(v1) | vpmovswb Wx,Vx (F3),(ev)
7200 ++21: vpmovsxbd Vx,Ux/Md (66),(v1) | vpmovsdb Wx,Vd (F3),(ev)
7201 ++22: vpmovsxbq Vx,Ux/Mw (66),(v1) | vpmovsqb Wx,Vq (F3),(ev)
7202 ++23: vpmovsxwd Vx,Ux/Mq (66),(v1) | vpmovsdw Wx,Vd (F3),(ev)
7203 ++24: vpmovsxwq Vx,Ux/Md (66),(v1) | vpmovsqw Wx,Vq (F3),(ev)
7204 ++25: vpmovsxdq Vx,Ux/Mq (66),(v1) | vpmovsqd Wx,Vq (F3),(ev)
7205 ++26: vptestmb/w Vk,Hx,Wx (66),(ev) | vptestnmb/w Vk,Hx,Wx (F3),(ev)
7206 ++27: vptestmd/q Vk,Hx,Wx (66),(ev) | vptestnmd/q Vk,Hx,Wx (F3),(ev)
7207 ++28: vpmuldq Vx,Hx,Wx (66),(v1) | vpmovm2b/w Vx,Uk (F3),(ev)
7208 ++29: vpcmpeqq Vx,Hx,Wx (66),(v1) | vpmovb2m/w2m Vk,Ux (F3),(ev)
7209 ++2a: vmovntdqa Vx,Mx (66),(v1) | vpbroadcastmb2q Vx,Uk (F3),(ev)
7210 ++2b: vpackusdw Vx,Hx,Wx (66),(v1)
7211 ++2c: vmaskmovps Vx,Hx,Mx (66),(v) | vscalefps/d Vx,Hx,Wx (66),(evo)
7212 ++2d: vmaskmovpd Vx,Hx,Mx (66),(v) | vscalefss/d Vx,Hx,Wx (66),(evo)
7213 ++2e: vmaskmovps Mx,Hx,Vx (66),(v)
7214 ++2f: vmaskmovpd Mx,Hx,Vx (66),(v)
7215 ++# 0x0f 0x38 0x30-0x3f
7216 ++30: vpmovzxbw Vx,Ux/Mq (66),(v1) | vpmovwb Wx,Vx (F3),(ev)
7217 ++31: vpmovzxbd Vx,Ux/Md (66),(v1) | vpmovdb Wx,Vd (F3),(ev)
7218 ++32: vpmovzxbq Vx,Ux/Mw (66),(v1) | vpmovqb Wx,Vq (F3),(ev)
7219 ++33: vpmovzxwd Vx,Ux/Mq (66),(v1) | vpmovdw Wx,Vd (F3),(ev)
7220 ++34: vpmovzxwq Vx,Ux/Md (66),(v1) | vpmovqw Wx,Vq (F3),(ev)
7221 ++35: vpmovzxdq Vx,Ux/Mq (66),(v1) | vpmovqd Wx,Vq (F3),(ev)
7222 ++36: vpermd Vqq,Hqq,Wqq (66),(v) | vpermd/q Vqq,Hqq,Wqq (66),(evo)
7223 ++37: vpcmpgtq Vx,Hx,Wx (66),(v1)
7224 ++38: vpminsb Vx,Hx,Wx (66),(v1) | vpmovm2d/q Vx,Uk (F3),(ev)
7225 ++39: vpminsd Vx,Hx,Wx (66),(v1) | vpminsd/q Vx,Hx,Wx (66),(evo) | vpmovd2m/q2m Vk,Ux (F3),(ev)
7226 ++3a: vpminuw Vx,Hx,Wx (66),(v1) | vpbroadcastmw2d Vx,Uk (F3),(ev)
7227 ++3b: vpminud Vx,Hx,Wx (66),(v1) | vpminud/q Vx,Hx,Wx (66),(evo)
7228 ++3c: vpmaxsb Vx,Hx,Wx (66),(v1)
7229 ++3d: vpmaxsd Vx,Hx,Wx (66),(v1) | vpmaxsd/q Vx,Hx,Wx (66),(evo)
7230 ++3e: vpmaxuw Vx,Hx,Wx (66),(v1)
7231 ++3f: vpmaxud Vx,Hx,Wx (66),(v1) | vpmaxud/q Vx,Hx,Wx (66),(evo)
7232 ++# 0x0f 0x38 0x40-0x8f
7233 ++40: vpmulld Vx,Hx,Wx (66),(v1) | vpmulld/q Vx,Hx,Wx (66),(evo)
7234 ++41: vphminposuw Vdq,Wdq (66),(v1)
7235 ++42: vgetexpps/d Vx,Wx (66),(ev)
7236 ++43: vgetexpss/d Vx,Hx,Wx (66),(ev)
7237 ++44: vplzcntd/q Vx,Wx (66),(ev)
7238 ++45: vpsrlvd/q Vx,Hx,Wx (66),(v)
7239 ++46: vpsravd Vx,Hx,Wx (66),(v) | vpsravd/q Vx,Hx,Wx (66),(evo)
7240 ++47: vpsllvd/q Vx,Hx,Wx (66),(v)
7241 ++# Skip 0x48-0x4b
7242 ++4c: vrcp14ps/d Vpd,Wpd (66),(ev)
7243 ++4d: vrcp14ss/d Vsd,Hpd,Wsd (66),(ev)
7244 ++4e: vrsqrt14ps/d Vpd,Wpd (66),(ev)
7245 ++4f: vrsqrt14ss/d Vsd,Hsd,Wsd (66),(ev)
7246 ++# Skip 0x50-0x57
7247 ++58: vpbroadcastd Vx,Wx (66),(v)
7248 ++59: vpbroadcastq Vx,Wx (66),(v) | vbroadcasti32x2 Vx,Wx (66),(evo)
7249 ++5a: vbroadcasti128 Vqq,Mdq (66),(v) | vbroadcasti32x4/64x2 Vx,Wx (66),(evo)
7250 ++5b: vbroadcasti32x8/64x4 Vqq,Mdq (66),(ev)
7251 ++# Skip 0x5c-0x63
7252 ++64: vpblendmd/q Vx,Hx,Wx (66),(ev)
7253 ++65: vblendmps/d Vx,Hx,Wx (66),(ev)
7254 ++66: vpblendmb/w Vx,Hx,Wx (66),(ev)
7255 ++# Skip 0x67-0x74
7256 ++75: vpermi2b/w Vx,Hx,Wx (66),(ev)
7257 ++76: vpermi2d/q Vx,Hx,Wx (66),(ev)
7258 ++77: vpermi2ps/d Vx,Hx,Wx (66),(ev)
7259 ++78: vpbroadcastb Vx,Wx (66),(v)
7260 ++79: vpbroadcastw Vx,Wx (66),(v)
7261 ++7a: vpbroadcastb Vx,Rv (66),(ev)
7262 ++7b: vpbroadcastw Vx,Rv (66),(ev)
7263 ++7c: vpbroadcastd/q Vx,Rv (66),(ev)
7264 ++7d: vpermt2b/w Vx,Hx,Wx (66),(ev)
7265 ++7e: vpermt2d/q Vx,Hx,Wx (66),(ev)
7266 ++7f: vpermt2ps/d Vx,Hx,Wx (66),(ev)
7267 ++80: INVEPT Gy,Mdq (66)
7268 ++81: INVPID Gy,Mdq (66)
7269 ++82: INVPCID Gy,Mdq (66)
7270 ++83: vpmultishiftqb Vx,Hx,Wx (66),(ev)
7271 ++88: vexpandps/d Vpd,Wpd (66),(ev)
7272 ++89: vpexpandd/q Vx,Wx (66),(ev)
7273 ++8a: vcompressps/d Wx,Vx (66),(ev)
7274 ++8b: vpcompressd/q Wx,Vx (66),(ev)
7275 ++8c: vpmaskmovd/q Vx,Hx,Mx (66),(v)
7276 ++8d: vpermb/w Vx,Hx,Wx (66),(ev)
7277 ++8e: vpmaskmovd/q Mx,Vx,Hx (66),(v)
7278 ++# 0x0f 0x38 0x90-0xbf (FMA)
7279 ++90: vgatherdd/q Vx,Hx,Wx (66),(v) | vpgatherdd/q Vx,Wx (66),(evo)
7280 ++91: vgatherqd/q Vx,Hx,Wx (66),(v) | vpgatherqd/q Vx,Wx (66),(evo)
7281 ++92: vgatherdps/d Vx,Hx,Wx (66),(v)
7282 ++93: vgatherqps/d Vx,Hx,Wx (66),(v)
7283 ++94:
7284 ++95:
7285 ++96: vfmaddsub132ps/d Vx,Hx,Wx (66),(v)
7286 ++97: vfmsubadd132ps/d Vx,Hx,Wx (66),(v)
7287 ++98: vfmadd132ps/d Vx,Hx,Wx (66),(v)
7288 ++99: vfmadd132ss/d Vx,Hx,Wx (66),(v),(v1)
7289 ++9a: vfmsub132ps/d Vx,Hx,Wx (66),(v)
7290 ++9b: vfmsub132ss/d Vx,Hx,Wx (66),(v),(v1)
7291 ++9c: vfnmadd132ps/d Vx,Hx,Wx (66),(v)
7292 ++9d: vfnmadd132ss/d Vx,Hx,Wx (66),(v),(v1)
7293 ++9e: vfnmsub132ps/d Vx,Hx,Wx (66),(v)
7294 ++9f: vfnmsub132ss/d Vx,Hx,Wx (66),(v),(v1)
7295 ++a0: vpscatterdd/q Wx,Vx (66),(ev)
7296 ++a1: vpscatterqd/q Wx,Vx (66),(ev)
7297 ++a2: vscatterdps/d Wx,Vx (66),(ev)
7298 ++a3: vscatterqps/d Wx,Vx (66),(ev)
7299 ++a6: vfmaddsub213ps/d Vx,Hx,Wx (66),(v)
7300 ++a7: vfmsubadd213ps/d Vx,Hx,Wx (66),(v)
7301 ++a8: vfmadd213ps/d Vx,Hx,Wx (66),(v)
7302 ++a9: vfmadd213ss/d Vx,Hx,Wx (66),(v),(v1)
7303 ++aa: vfmsub213ps/d Vx,Hx,Wx (66),(v)
7304 ++ab: vfmsub213ss/d Vx,Hx,Wx (66),(v),(v1)
7305 ++ac: vfnmadd213ps/d Vx,Hx,Wx (66),(v)
7306 ++ad: vfnmadd213ss/d Vx,Hx,Wx (66),(v),(v1)
7307 ++ae: vfnmsub213ps/d Vx,Hx,Wx (66),(v)
7308 ++af: vfnmsub213ss/d Vx,Hx,Wx (66),(v),(v1)
7309 ++b4: vpmadd52luq Vx,Hx,Wx (66),(ev)
7310 ++b5: vpmadd52huq Vx,Hx,Wx (66),(ev)
7311 ++b6: vfmaddsub231ps/d Vx,Hx,Wx (66),(v)
7312 ++b7: vfmsubadd231ps/d Vx,Hx,Wx (66),(v)
7313 ++b8: vfmadd231ps/d Vx,Hx,Wx (66),(v)
7314 ++b9: vfmadd231ss/d Vx,Hx,Wx (66),(v),(v1)
7315 ++ba: vfmsub231ps/d Vx,Hx,Wx (66),(v)
7316 ++bb: vfmsub231ss/d Vx,Hx,Wx (66),(v),(v1)
7317 ++bc: vfnmadd231ps/d Vx,Hx,Wx (66),(v)
7318 ++bd: vfnmadd231ss/d Vx,Hx,Wx (66),(v),(v1)
7319 ++be: vfnmsub231ps/d Vx,Hx,Wx (66),(v)
7320 ++bf: vfnmsub231ss/d Vx,Hx,Wx (66),(v),(v1)
7321 ++# 0x0f 0x38 0xc0-0xff
7322 ++c4: vpconflictd/q Vx,Wx (66),(ev)
7323 ++c6: Grp18 (1A)
7324 ++c7: Grp19 (1A)
7325 ++c8: sha1nexte Vdq,Wdq | vexp2ps/d Vx,Wx (66),(ev)
7326 ++c9: sha1msg1 Vdq,Wdq
7327 ++ca: sha1msg2 Vdq,Wdq | vrcp28ps/d Vx,Wx (66),(ev)
7328 ++cb: sha256rnds2 Vdq,Wdq | vrcp28ss/d Vx,Hx,Wx (66),(ev)
7329 ++cc: sha256msg1 Vdq,Wdq | vrsqrt28ps/d Vx,Wx (66),(ev)
7330 ++cd: sha256msg2 Vdq,Wdq | vrsqrt28ss/d Vx,Hx,Wx (66),(ev)
7331 ++db: VAESIMC Vdq,Wdq (66),(v1)
7332 ++dc: VAESENC Vdq,Hdq,Wdq (66),(v1)
7333 ++dd: VAESENCLAST Vdq,Hdq,Wdq (66),(v1)
7334 ++de: VAESDEC Vdq,Hdq,Wdq (66),(v1)
7335 ++df: VAESDECLAST Vdq,Hdq,Wdq (66),(v1)
7336 ++f0: MOVBE Gy,My | MOVBE Gw,Mw (66) | CRC32 Gd,Eb (F2) | CRC32 Gd,Eb (66&F2)
7337 ++f1: MOVBE My,Gy | MOVBE Mw,Gw (66) | CRC32 Gd,Ey (F2) | CRC32 Gd,Ew (66&F2)
7338 ++f2: ANDN Gy,By,Ey (v)
7339 ++f3: Grp17 (1A)
7340 ++f5: BZHI Gy,Ey,By (v) | PEXT Gy,By,Ey (F3),(v) | PDEP Gy,By,Ey (F2),(v)
7341 ++f6: ADCX Gy,Ey (66) | ADOX Gy,Ey (F3) | MULX By,Gy,rDX,Ey (F2),(v)
7342 ++f7: BEXTR Gy,Ey,By (v) | SHLX Gy,Ey,By (66),(v) | SARX Gy,Ey,By (F3),(v) | SHRX Gy,Ey,By (F2),(v)
7343 ++EndTable
7344 ++
7345 ++Table: 3-byte opcode 2 (0x0f 0x3a)
7346 ++Referrer: 3-byte escape 2
7347 ++AVXcode: 3
7348 ++# 0x0f 0x3a 0x00-0xff
7349 ++00: vpermq Vqq,Wqq,Ib (66),(v)
7350 ++01: vpermpd Vqq,Wqq,Ib (66),(v)
7351 ++02: vpblendd Vx,Hx,Wx,Ib (66),(v)
7352 ++03: valignd/q Vx,Hx,Wx,Ib (66),(ev)
7353 ++04: vpermilps Vx,Wx,Ib (66),(v)
7354 ++05: vpermilpd Vx,Wx,Ib (66),(v)
7355 ++06: vperm2f128 Vqq,Hqq,Wqq,Ib (66),(v)
7356 ++07:
7357 ++08: vroundps Vx,Wx,Ib (66) | vrndscaleps Vx,Wx,Ib (66),(evo)
7358 ++09: vroundpd Vx,Wx,Ib (66) | vrndscalepd Vx,Wx,Ib (66),(evo)
7359 ++0a: vroundss Vss,Wss,Ib (66),(v1) | vrndscaless Vx,Hx,Wx,Ib (66),(evo)
7360 ++0b: vroundsd Vsd,Wsd,Ib (66),(v1) | vrndscalesd Vx,Hx,Wx,Ib (66),(evo)
7361 ++0c: vblendps Vx,Hx,Wx,Ib (66)
7362 ++0d: vblendpd Vx,Hx,Wx,Ib (66)
7363 ++0e: vpblendw Vx,Hx,Wx,Ib (66),(v1)
7364 ++0f: palignr Pq,Qq,Ib | vpalignr Vx,Hx,Wx,Ib (66),(v1)
7365 ++14: vpextrb Rd/Mb,Vdq,Ib (66),(v1)
7366 ++15: vpextrw Rd/Mw,Vdq,Ib (66),(v1)
7367 ++16: vpextrd/q Ey,Vdq,Ib (66),(v1)
7368 ++17: vextractps Ed,Vdq,Ib (66),(v1)
7369 ++18: vinsertf128 Vqq,Hqq,Wqq,Ib (66),(v) | vinsertf32x4/64x2 Vqq,Hqq,Wqq,Ib (66),(evo)
7370 ++19: vextractf128 Wdq,Vqq,Ib (66),(v) | vextractf32x4/64x2 Wdq,Vqq,Ib (66),(evo)
7371 ++1a: vinsertf32x8/64x4 Vqq,Hqq,Wqq,Ib (66),(ev)
7372 ++1b: vextractf32x8/64x4 Wdq,Vqq,Ib (66),(ev)
7373 ++1d: vcvtps2ph Wx,Vx,Ib (66),(v)
7374 ++1e: vpcmpud/q Vk,Hd,Wd,Ib (66),(ev)
7375 ++1f: vpcmpd/q Vk,Hd,Wd,Ib (66),(ev)
7376 ++20: vpinsrb Vdq,Hdq,Ry/Mb,Ib (66),(v1)
7377 ++21: vinsertps Vdq,Hdq,Udq/Md,Ib (66),(v1)
7378 ++22: vpinsrd/q Vdq,Hdq,Ey,Ib (66),(v1)
7379 ++23: vshuff32x4/64x2 Vx,Hx,Wx,Ib (66),(ev)
7380 ++25: vpternlogd/q Vx,Hx,Wx,Ib (66),(ev)
7381 ++26: vgetmantps/d Vx,Wx,Ib (66),(ev)
7382 ++27: vgetmantss/d Vx,Hx,Wx,Ib (66),(ev)
7383 ++30: kshiftrb/w Vk,Uk,Ib (66),(v)
7384 ++31: kshiftrd/q Vk,Uk,Ib (66),(v)
7385 ++32: kshiftlb/w Vk,Uk,Ib (66),(v)
7386 ++33: kshiftld/q Vk,Uk,Ib (66),(v)
7387 ++38: vinserti128 Vqq,Hqq,Wqq,Ib (66),(v) | vinserti32x4/64x2 Vqq,Hqq,Wqq,Ib (66),(evo)
7388 ++39: vextracti128 Wdq,Vqq,Ib (66),(v) | vextracti32x4/64x2 Wdq,Vqq,Ib (66),(evo)
7389 ++3a: vinserti32x8/64x4 Vqq,Hqq,Wqq,Ib (66),(ev)
7390 ++3b: vextracti32x8/64x4 Wdq,Vqq,Ib (66),(ev)
7391 ++3e: vpcmpub/w Vk,Hk,Wx,Ib (66),(ev)
7392 ++3f: vpcmpb/w Vk,Hk,Wx,Ib (66),(ev)
7393 ++40: vdpps Vx,Hx,Wx,Ib (66)
7394 ++41: vdppd Vdq,Hdq,Wdq,Ib (66),(v1)
7395 ++42: vmpsadbw Vx,Hx,Wx,Ib (66),(v1) | vdbpsadbw Vx,Hx,Wx,Ib (66),(evo)
7396 ++43: vshufi32x4/64x2 Vx,Hx,Wx,Ib (66),(ev)
7397 ++44: vpclmulqdq Vdq,Hdq,Wdq,Ib (66),(v1)
7398 ++46: vperm2i128 Vqq,Hqq,Wqq,Ib (66),(v)
7399 ++4a: vblendvps Vx,Hx,Wx,Lx (66),(v)
7400 ++4b: vblendvpd Vx,Hx,Wx,Lx (66),(v)
7401 ++4c: vpblendvb Vx,Hx,Wx,Lx (66),(v1)
7402 ++50: vrangeps/d Vx,Hx,Wx,Ib (66),(ev)
7403 ++51: vrangess/d Vx,Hx,Wx,Ib (66),(ev)
7404 ++54: vfixupimmps/d Vx,Hx,Wx,Ib (66),(ev)
7405 ++55: vfixupimmss/d Vx,Hx,Wx,Ib (66),(ev)
7406 ++56: vreduceps/d Vx,Wx,Ib (66),(ev)
7407 ++57: vreducess/d Vx,Hx,Wx,Ib (66),(ev)
7408 ++60: vpcmpestrm Vdq,Wdq,Ib (66),(v1)
7409 ++61: vpcmpestri Vdq,Wdq,Ib (66),(v1)
7410 ++62: vpcmpistrm Vdq,Wdq,Ib (66),(v1)
7411 ++63: vpcmpistri Vdq,Wdq,Ib (66),(v1)
7412 ++66: vfpclassps/d Vk,Wx,Ib (66),(ev)
7413 ++67: vfpclassss/d Vk,Wx,Ib (66),(ev)
7414 ++cc: sha1rnds4 Vdq,Wdq,Ib
7415 ++df: VAESKEYGEN Vdq,Wdq,Ib (66),(v1)
7416 ++f0: RORX Gy,Ey,Ib (F2),(v)
7417 ++EndTable
7418 ++
7419 ++GrpTable: Grp1
7420 ++0: ADD
7421 ++1: OR
7422 ++2: ADC
7423 ++3: SBB
7424 ++4: AND
7425 ++5: SUB
7426 ++6: XOR
7427 ++7: CMP
7428 ++EndTable
7429 ++
7430 ++GrpTable: Grp1A
7431 ++0: POP
7432 ++EndTable
7433 ++
7434 ++GrpTable: Grp2
7435 ++0: ROL
7436 ++1: ROR
7437 ++2: RCL
7438 ++3: RCR
7439 ++4: SHL/SAL
7440 ++5: SHR
7441 ++6:
7442 ++7: SAR
7443 ++EndTable
7444 ++
7445 ++GrpTable: Grp3_1
7446 ++0: TEST Eb,Ib
7447 ++1: TEST Eb,Ib
7448 ++2: NOT Eb
7449 ++3: NEG Eb
7450 ++4: MUL AL,Eb
7451 ++5: IMUL AL,Eb
7452 ++6: DIV AL,Eb
7453 ++7: IDIV AL,Eb
7454 ++EndTable
7455 ++
7456 ++GrpTable: Grp3_2
7457 ++0: TEST Ev,Iz
7458 ++1:
7459 ++2: NOT Ev
7460 ++3: NEG Ev
7461 ++4: MUL rAX,Ev
7462 ++5: IMUL rAX,Ev
7463 ++6: DIV rAX,Ev
7464 ++7: IDIV rAX,Ev
7465 ++EndTable
7466 ++
7467 ++GrpTable: Grp4
7468 ++0: INC Eb
7469 ++1: DEC Eb
7470 ++EndTable
7471 ++
7472 ++GrpTable: Grp5
7473 ++0: INC Ev
7474 ++1: DEC Ev
7475 ++# Note: "forced64" is Intel CPU behavior (see comment about CALL insn).
7476 ++2: CALLN Ev (f64)
7477 ++3: CALLF Ep
7478 ++4: JMPN Ev (f64)
7479 ++5: JMPF Mp
7480 ++6: PUSH Ev (d64)
7481 ++7:
7482 ++EndTable
7483 ++
7484 ++GrpTable: Grp6
7485 ++0: SLDT Rv/Mw
7486 ++1: STR Rv/Mw
7487 ++2: LLDT Ew
7488 ++3: LTR Ew
7489 ++4: VERR Ew
7490 ++5: VERW Ew
7491 ++EndTable
7492 ++
7493 ++GrpTable: Grp7
7494 ++0: SGDT Ms | VMCALL (001),(11B) | VMLAUNCH (010),(11B) | VMRESUME (011),(11B) | VMXOFF (100),(11B)
7495 ++1: SIDT Ms | MONITOR (000),(11B) | MWAIT (001),(11B) | CLAC (010),(11B) | STAC (011),(11B)
7496 ++2: LGDT Ms | XGETBV (000),(11B) | XSETBV (001),(11B) | VMFUNC (100),(11B) | XEND (101)(11B) | XTEST (110)(11B)
7497 ++3: LIDT Ms
7498 ++4: SMSW Mw/Rv
7499 ++5: rdpkru (110),(11B) | wrpkru (111),(11B)
7500 ++6: LMSW Ew
7501 ++7: INVLPG Mb | SWAPGS (o64),(000),(11B) | RDTSCP (001),(11B)
7502 ++EndTable
7503 ++
7504 ++GrpTable: Grp8
7505 ++4: BT
7506 ++5: BTS
7507 ++6: BTR
7508 ++7: BTC
7509 ++EndTable
7510 ++
7511 ++GrpTable: Grp9
7512 ++1: CMPXCHG8B/16B Mq/Mdq
7513 ++3: xrstors
7514 ++4: xsavec
7515 ++5: xsaves
7516 ++6: VMPTRLD Mq | VMCLEAR Mq (66) | VMXON Mq (F3) | RDRAND Rv (11B)
7517 ++7: VMPTRST Mq | VMPTRST Mq (F3) | RDSEED Rv (11B)
7518 ++EndTable
7519 ++
7520 ++GrpTable: Grp10
7521 ++EndTable
7522 ++
7523 ++# Grp11A and Grp11B are expressed as Grp11 in Intel SDM
7524 ++GrpTable: Grp11A
7525 ++0: MOV Eb,Ib
7526 ++7: XABORT Ib (000),(11B)
7527 ++EndTable
7528 ++
7529 ++GrpTable: Grp11B
7530 ++0: MOV Eb,Iz
7531 ++7: XBEGIN Jz (000),(11B)
7532 ++EndTable
7533 ++
7534 ++GrpTable: Grp12
7535 ++2: psrlw Nq,Ib (11B) | vpsrlw Hx,Ux,Ib (66),(11B),(v1)
7536 ++4: psraw Nq,Ib (11B) | vpsraw Hx,Ux,Ib (66),(11B),(v1)
7537 ++6: psllw Nq,Ib (11B) | vpsllw Hx,Ux,Ib (66),(11B),(v1)
7538 ++EndTable
7539 ++
7540 ++GrpTable: Grp13
7541 ++0: vprord/q Hx,Wx,Ib (66),(ev)
7542 ++1: vprold/q Hx,Wx,Ib (66),(ev)
7543 ++2: psrld Nq,Ib (11B) | vpsrld Hx,Ux,Ib (66),(11B),(v1)
7544 ++4: psrad Nq,Ib (11B) | vpsrad Hx,Ux,Ib (66),(11B),(v1) | vpsrad/q Hx,Ux,Ib (66),(evo)
7545 ++6: pslld Nq,Ib (11B) | vpslld Hx,Ux,Ib (66),(11B),(v1)
7546 ++EndTable
7547 ++
7548 ++GrpTable: Grp14
7549 ++2: psrlq Nq,Ib (11B) | vpsrlq Hx,Ux,Ib (66),(11B),(v1)
7550 ++3: vpsrldq Hx,Ux,Ib (66),(11B),(v1)
7551 ++6: psllq Nq,Ib (11B) | vpsllq Hx,Ux,Ib (66),(11B),(v1)
7552 ++7: vpslldq Hx,Ux,Ib (66),(11B),(v1)
7553 ++EndTable
7554 ++
7555 ++GrpTable: Grp15
7556 ++0: fxsave | RDFSBASE Ry (F3),(11B)
7557 ++1: fxstor | RDGSBASE Ry (F3),(11B)
7558 ++2: vldmxcsr Md (v1) | WRFSBASE Ry (F3),(11B)
7559 ++3: vstmxcsr Md (v1) | WRGSBASE Ry (F3),(11B)
7560 ++4: XSAVE
7561 ++5: XRSTOR | lfence (11B)
7562 ++6: XSAVEOPT | clwb (66) | mfence (11B)
7563 ++7: clflush | clflushopt (66) | sfence (11B)
7564 ++EndTable
7565 ++
7566 ++GrpTable: Grp16
7567 ++0: prefetch NTA
7568 ++1: prefetch T0
7569 ++2: prefetch T1
7570 ++3: prefetch T2
7571 ++EndTable
7572 ++
7573 ++GrpTable: Grp17
7574 ++1: BLSR By,Ey (v)
7575 ++2: BLSMSK By,Ey (v)
7576 ++3: BLSI By,Ey (v)
7577 ++EndTable
7578 ++
7579 ++GrpTable: Grp18
7580 ++1: vgatherpf0dps/d Wx (66),(ev)
7581 ++2: vgatherpf1dps/d Wx (66),(ev)
7582 ++5: vscatterpf0dps/d Wx (66),(ev)
7583 ++6: vscatterpf1dps/d Wx (66),(ev)
7584 ++EndTable
7585 ++
7586 ++GrpTable: Grp19
7587 ++1: vgatherpf0qps/d Wx (66),(ev)
7588 ++2: vgatherpf1qps/d Wx (66),(ev)
7589 ++5: vscatterpf0qps/d Wx (66),(ev)
7590 ++6: vscatterpf1qps/d Wx (66),(ev)
7591 ++EndTable
7592 ++
7593 ++# AMD's Prefetch Group
7594 ++GrpTable: GrpP
7595 ++0: PREFETCH
7596 ++1: PREFETCHW
7597 ++EndTable
7598 ++
7599 ++GrpTable: GrpPDLK
7600 ++0: MONTMUL
7601 ++1: XSHA1
7602 ++2: XSHA2
7603 ++EndTable
7604 ++
7605 ++GrpTable: GrpRNG
7606 ++0: xstore-rng
7607 ++1: xcrypt-ecb
7608 ++2: xcrypt-cbc
7609 ++4: xcrypt-cfb
7610 ++5: xcrypt-ofb
7611 ++EndTable
7612 +diff --git a/tools/objtool/arch/x86/tools/gen-insn-attr-x86.awk b/tools/objtool/arch/x86/tools/gen-insn-attr-x86.awk
7613 +new file mode 100644
7614 +index 000000000000..a3d2c62fd805
7615 +--- /dev/null
7616 ++++ b/tools/objtool/arch/x86/tools/gen-insn-attr-x86.awk
7617 +@@ -0,0 +1,392 @@
7618 ++#!/bin/awk -f
7619 ++# gen-insn-attr-x86.awk: Instruction attribute table generator
7620 ++# Written by Masami Hiramatsu <mhiramat@××××××.com>
7621 ++#
7622 ++# Usage: awk -f gen-insn-attr-x86.awk x86-opcode-map.txt > inat-tables.c
7623 ++
7624 ++# Awk implementation sanity check
7625 ++function check_awk_implement() {
7626 ++ if (sprintf("%x", 0) != "0")
7627 ++ return "Your awk has a printf-format problem."
7628 ++ return ""
7629 ++}
7630 ++
7631 ++# Clear working vars
7632 ++function clear_vars() {
7633 ++ delete table
7634 ++ delete lptable2
7635 ++ delete lptable1
7636 ++ delete lptable3
7637 ++ eid = -1 # escape id
7638 ++ gid = -1 # group id
7639 ++ aid = -1 # AVX id
7640 ++ tname = ""
7641 ++}
7642 ++
7643 ++BEGIN {
7644 ++ # Implementation error checking
7645 ++ awkchecked = check_awk_implement()
7646 ++ if (awkchecked != "") {
7647 ++ print "Error: " awkchecked > "/dev/stderr"
7648 ++ print "Please try to use gawk." > "/dev/stderr"
7649 ++ exit 1
7650 ++ }
7651 ++
7652 ++ # Setup generating tables
7653 ++ print "/* x86 opcode map generated from x86-opcode-map.txt */"
7654 ++ print "/* Do not change this code. */\n"
7655 ++ ggid = 1
7656 ++ geid = 1
7657 ++ gaid = 0
7658 ++ delete etable
7659 ++ delete gtable
7660 ++ delete atable
7661 ++
7662 ++ opnd_expr = "^[A-Za-z/]"
7663 ++ ext_expr = "^\\("
7664 ++ sep_expr = "^\\|$"
7665 ++ group_expr = "^Grp[0-9A-Za-z]+"
7666 ++
7667 ++ imm_expr = "^[IJAOL][a-z]"
7668 ++ imm_flag["Ib"] = "INAT_MAKE_IMM(INAT_IMM_BYTE)"
7669 ++ imm_flag["Jb"] = "INAT_MAKE_IMM(INAT_IMM_BYTE)"
7670 ++ imm_flag["Iw"] = "INAT_MAKE_IMM(INAT_IMM_WORD)"
7671 ++ imm_flag["Id"] = "INAT_MAKE_IMM(INAT_IMM_DWORD)"
7672 ++ imm_flag["Iq"] = "INAT_MAKE_IMM(INAT_IMM_QWORD)"
7673 ++ imm_flag["Ap"] = "INAT_MAKE_IMM(INAT_IMM_PTR)"
7674 ++ imm_flag["Iz"] = "INAT_MAKE_IMM(INAT_IMM_VWORD32)"
7675 ++ imm_flag["Jz"] = "INAT_MAKE_IMM(INAT_IMM_VWORD32)"
7676 ++ imm_flag["Iv"] = "INAT_MAKE_IMM(INAT_IMM_VWORD)"
7677 ++ imm_flag["Ob"] = "INAT_MOFFSET"
7678 ++ imm_flag["Ov"] = "INAT_MOFFSET"
7679 ++ imm_flag["Lx"] = "INAT_MAKE_IMM(INAT_IMM_BYTE)"
7680 ++
7681 ++ modrm_expr = "^([CDEGMNPQRSUVW/][a-z]+|NTA|T[012])"
7682 ++ force64_expr = "\\([df]64\\)"
7683 ++ rex_expr = "^REX(\\.[XRWB]+)*"
7684 ++ fpu_expr = "^ESC" # TODO
7685 ++
7686 ++ lprefix1_expr = "\\((66|!F3)\\)"
7687 ++ lprefix2_expr = "\\(F3\\)"
7688 ++ lprefix3_expr = "\\((F2|!F3|66\\&F2)\\)"
7689 ++ lprefix_expr = "\\((66|F2|F3)\\)"
7690 ++ max_lprefix = 4
7691 ++
7692 ++ # All opcodes starting with lower-case 'v', 'k' or with (v1) superscript
7693 ++ # accepts VEX prefix
7694 ++ vexok_opcode_expr = "^[vk].*"
7695 ++ vexok_expr = "\\(v1\\)"
7696 ++ # All opcodes with (v) superscript supports *only* VEX prefix
7697 ++ vexonly_expr = "\\(v\\)"
7698 ++ # All opcodes with (ev) superscript supports *only* EVEX prefix
7699 ++ evexonly_expr = "\\(ev\\)"
7700 ++
7701 ++ prefix_expr = "\\(Prefix\\)"
7702 ++ prefix_num["Operand-Size"] = "INAT_PFX_OPNDSZ"
7703 ++ prefix_num["REPNE"] = "INAT_PFX_REPNE"
7704 ++ prefix_num["REP/REPE"] = "INAT_PFX_REPE"
7705 ++ prefix_num["XACQUIRE"] = "INAT_PFX_REPNE"
7706 ++ prefix_num["XRELEASE"] = "INAT_PFX_REPE"
7707 ++ prefix_num["LOCK"] = "INAT_PFX_LOCK"
7708 ++ prefix_num["SEG=CS"] = "INAT_PFX_CS"
7709 ++ prefix_num["SEG=DS"] = "INAT_PFX_DS"
7710 ++ prefix_num["SEG=ES"] = "INAT_PFX_ES"
7711 ++ prefix_num["SEG=FS"] = "INAT_PFX_FS"
7712 ++ prefix_num["SEG=GS"] = "INAT_PFX_GS"
7713 ++ prefix_num["SEG=SS"] = "INAT_PFX_SS"
7714 ++ prefix_num["Address-Size"] = "INAT_PFX_ADDRSZ"
7715 ++ prefix_num["VEX+1byte"] = "INAT_PFX_VEX2"
7716 ++ prefix_num["VEX+2byte"] = "INAT_PFX_VEX3"
7717 ++ prefix_num["EVEX"] = "INAT_PFX_EVEX"
7718 ++
7719 ++ clear_vars()
7720 ++}
7721 ++
7722 ++function semantic_error(msg) {
7723 ++ print "Semantic error at " NR ": " msg > "/dev/stderr"
7724 ++ exit 1
7725 ++}
7726 ++
7727 ++function debug(msg) {
7728 ++ print "DEBUG: " msg
7729 ++}
7730 ++
7731 ++function array_size(arr, i,c) {
7732 ++ c = 0
7733 ++ for (i in arr)
7734 ++ c++
7735 ++ return c
7736 ++}
7737 ++
7738 ++/^Table:/ {
7739 ++ print "/* " $0 " */"
7740 ++ if (tname != "")
7741 ++ semantic_error("Hit Table: before EndTable:.");
7742 ++}
7743 ++
7744 ++/^Referrer:/ {
7745 ++ if (NF != 1) {
7746 ++ # escape opcode table
7747 ++ ref = ""
7748 ++ for (i = 2; i <= NF; i++)
7749 ++ ref = ref $i
7750 ++ eid = escape[ref]
7751 ++ tname = sprintf("inat_escape_table_%d", eid)
7752 ++ }
7753 ++}
7754 ++
7755 ++/^AVXcode:/ {
7756 ++ if (NF != 1) {
7757 ++ # AVX/escape opcode table
7758 ++ aid = $2
7759 ++ if (gaid <= aid)
7760 ++ gaid = aid + 1
7761 ++ if (tname == "") # AVX only opcode table
7762 ++ tname = sprintf("inat_avx_table_%d", $2)
7763 ++ }
7764 ++ if (aid == -1 && eid == -1) # primary opcode table
7765 ++ tname = "inat_primary_table"
7766 ++}
7767 ++
7768 ++/^GrpTable:/ {
7769 ++ print "/* " $0 " */"
7770 ++ if (!($2 in group))
7771 ++ semantic_error("No group: " $2 )
7772 ++ gid = group[$2]
7773 ++ tname = "inat_group_table_" gid
7774 ++}
7775 ++
7776 ++function print_table(tbl,name,fmt,n)
7777 ++{
7778 ++ print "const insn_attr_t " name " = {"
7779 ++ for (i = 0; i < n; i++) {
7780 ++ id = sprintf(fmt, i)
7781 ++ if (tbl[id])
7782 ++ print " [" id "] = " tbl[id] ","
7783 ++ }
7784 ++ print "};"
7785 ++}
7786 ++
7787 ++/^EndTable/ {
7788 ++ if (gid != -1) {
7789 ++ # print group tables
7790 ++ if (array_size(table) != 0) {
7791 ++ print_table(table, tname "[INAT_GROUP_TABLE_SIZE]",
7792 ++ "0x%x", 8)
7793 ++ gtable[gid,0] = tname
7794 ++ }
7795 ++ if (array_size(lptable1) != 0) {
7796 ++ print_table(lptable1, tname "_1[INAT_GROUP_TABLE_SIZE]",
7797 ++ "0x%x", 8)
7798 ++ gtable[gid,1] = tname "_1"
7799 ++ }
7800 ++ if (array_size(lptable2) != 0) {
7801 ++ print_table(lptable2, tname "_2[INAT_GROUP_TABLE_SIZE]",
7802 ++ "0x%x", 8)
7803 ++ gtable[gid,2] = tname "_2"
7804 ++ }
7805 ++ if (array_size(lptable3) != 0) {
7806 ++ print_table(lptable3, tname "_3[INAT_GROUP_TABLE_SIZE]",
7807 ++ "0x%x", 8)
7808 ++ gtable[gid,3] = tname "_3"
7809 ++ }
7810 ++ } else {
7811 ++ # print primary/escaped tables
7812 ++ if (array_size(table) != 0) {
7813 ++ print_table(table, tname "[INAT_OPCODE_TABLE_SIZE]",
7814 ++ "0x%02x", 256)
7815 ++ etable[eid,0] = tname
7816 ++ if (aid >= 0)
7817 ++ atable[aid,0] = tname
7818 ++ }
7819 ++ if (array_size(lptable1) != 0) {
7820 ++ print_table(lptable1,tname "_1[INAT_OPCODE_TABLE_SIZE]",
7821 ++ "0x%02x", 256)
7822 ++ etable[eid,1] = tname "_1"
7823 ++ if (aid >= 0)
7824 ++ atable[aid,1] = tname "_1"
7825 ++ }
7826 ++ if (array_size(lptable2) != 0) {
7827 ++ print_table(lptable2,tname "_2[INAT_OPCODE_TABLE_SIZE]",
7828 ++ "0x%02x", 256)
7829 ++ etable[eid,2] = tname "_2"
7830 ++ if (aid >= 0)
7831 ++ atable[aid,2] = tname "_2"
7832 ++ }
7833 ++ if (array_size(lptable3) != 0) {
7834 ++ print_table(lptable3,tname "_3[INAT_OPCODE_TABLE_SIZE]",
7835 ++ "0x%02x", 256)
7836 ++ etable[eid,3] = tname "_3"
7837 ++ if (aid >= 0)
7838 ++ atable[aid,3] = tname "_3"
7839 ++ }
7840 ++ }
7841 ++ print ""
7842 ++ clear_vars()
7843 ++}
7844 ++
7845 ++function add_flags(old,new) {
7846 ++ if (old && new)
7847 ++ return old " | " new
7848 ++ else if (old)
7849 ++ return old
7850 ++ else
7851 ++ return new
7852 ++}
7853 ++
7854 ++# convert operands to flags.
7855 ++function convert_operands(count,opnd, i,j,imm,mod)
7856 ++{
7857 ++ imm = null
7858 ++ mod = null
7859 ++ for (j = 1; j <= count; j++) {
7860 ++ i = opnd[j]
7861 ++ if (match(i, imm_expr) == 1) {
7862 ++ if (!imm_flag[i])
7863 ++ semantic_error("Unknown imm opnd: " i)
7864 ++ if (imm) {
7865 ++ if (i != "Ib")
7866 ++ semantic_error("Second IMM error")
7867 ++ imm = add_flags(imm, "INAT_SCNDIMM")
7868 ++ } else
7869 ++ imm = imm_flag[i]
7870 ++ } else if (match(i, modrm_expr))
7871 ++ mod = "INAT_MODRM"
7872 ++ }
7873 ++ return add_flags(imm, mod)
7874 ++}
7875 ++
7876 ++/^[0-9a-f]+\:/ {
7877 ++ if (NR == 1)
7878 ++ next
7879 ++ # get index
7880 ++ idx = "0x" substr($1, 1, index($1,":") - 1)
7881 ++ if (idx in table)
7882 ++ semantic_error("Redefine " idx " in " tname)
7883 ++
7884 ++ # check if escaped opcode
7885 ++ if ("escape" == $2) {
7886 ++ if ($3 != "#")
7887 ++ semantic_error("No escaped name")
7888 ++ ref = ""
7889 ++ for (i = 4; i <= NF; i++)
7890 ++ ref = ref $i
7891 ++ if (ref in escape)
7892 ++ semantic_error("Redefine escape (" ref ")")
7893 ++ escape[ref] = geid
7894 ++ geid++
7895 ++ table[idx] = "INAT_MAKE_ESCAPE(" escape[ref] ")"
7896 ++ next
7897 ++ }
7898 ++
7899 ++ variant = null
7900 ++ # converts
7901 ++ i = 2
7902 ++ while (i <= NF) {
7903 ++ opcode = $(i++)
7904 ++ delete opnds
7905 ++ ext = null
7906 ++ flags = null
7907 ++ opnd = null
7908 ++ # parse one opcode
7909 ++ if (match($i, opnd_expr)) {
7910 ++ opnd = $i
7911 ++ count = split($(i++), opnds, ",")
7912 ++ flags = convert_operands(count, opnds)
7913 ++ }
7914 ++ if (match($i, ext_expr))
7915 ++ ext = $(i++)
7916 ++ if (match($i, sep_expr))
7917 ++ i++
7918 ++ else if (i < NF)
7919 ++ semantic_error($i " is not a separator")
7920 ++
7921 ++ # check if group opcode
7922 ++ if (match(opcode, group_expr)) {
7923 ++ if (!(opcode in group)) {
7924 ++ group[opcode] = ggid
7925 ++ ggid++
7926 ++ }
7927 ++ flags = add_flags(flags, "INAT_MAKE_GROUP(" group[opcode] ")")
7928 ++ }
7929 ++ # check force(or default) 64bit
7930 ++ if (match(ext, force64_expr))
7931 ++ flags = add_flags(flags, "INAT_FORCE64")
7932 ++
7933 ++ # check REX prefix
7934 ++ if (match(opcode, rex_expr))
7935 ++ flags = add_flags(flags, "INAT_MAKE_PREFIX(INAT_PFX_REX)")
7936 ++
7937 ++ # check coprocessor escape : TODO
7938 ++ if (match(opcode, fpu_expr))
7939 ++ flags = add_flags(flags, "INAT_MODRM")
7940 ++
7941 ++ # check VEX codes
7942 ++ if (match(ext, evexonly_expr))
7943 ++ flags = add_flags(flags, "INAT_VEXOK | INAT_EVEXONLY")
7944 ++ else if (match(ext, vexonly_expr))
7945 ++ flags = add_flags(flags, "INAT_VEXOK | INAT_VEXONLY")
7946 ++ else if (match(ext, vexok_expr) || match(opcode, vexok_opcode_expr))
7947 ++ flags = add_flags(flags, "INAT_VEXOK")
7948 ++
7949 ++ # check prefixes
7950 ++ if (match(ext, prefix_expr)) {
7951 ++ if (!prefix_num[opcode])
7952 ++ semantic_error("Unknown prefix: " opcode)
7953 ++ flags = add_flags(flags, "INAT_MAKE_PREFIX(" prefix_num[opcode] ")")
7954 ++ }
7955 ++ if (length(flags) == 0)
7956 ++ continue
7957 ++ # check if last prefix
7958 ++ if (match(ext, lprefix1_expr)) {
7959 ++ lptable1[idx] = add_flags(lptable1[idx],flags)
7960 ++ variant = "INAT_VARIANT"
7961 ++ }
7962 ++ if (match(ext, lprefix2_expr)) {
7963 ++ lptable2[idx] = add_flags(lptable2[idx],flags)
7964 ++ variant = "INAT_VARIANT"
7965 ++ }
7966 ++ if (match(ext, lprefix3_expr)) {
7967 ++ lptable3[idx] = add_flags(lptable3[idx],flags)
7968 ++ variant = "INAT_VARIANT"
7969 ++ }
7970 ++ if (!match(ext, lprefix_expr)){
7971 ++ table[idx] = add_flags(table[idx],flags)
7972 ++ }
7973 ++ }
7974 ++ if (variant)
7975 ++ table[idx] = add_flags(table[idx],variant)
7976 ++}
7977 ++
7978 ++END {
7979 ++ if (awkchecked != "")
7980 ++ exit 1
7981 ++ # print escape opcode map's array
7982 ++ print "/* Escape opcode map array */"
7983 ++ print "const insn_attr_t * const inat_escape_tables[INAT_ESC_MAX + 1]" \
7984 ++ "[INAT_LSTPFX_MAX + 1] = {"
7985 ++ for (i = 0; i < geid; i++)
7986 ++ for (j = 0; j < max_lprefix; j++)
7987 ++ if (etable[i,j])
7988 ++ print " ["i"]["j"] = "etable[i,j]","
7989 ++ print "};\n"
7990 ++ # print group opcode map's array
7991 ++ print "/* Group opcode map array */"
7992 ++ print "const insn_attr_t * const inat_group_tables[INAT_GRP_MAX + 1]"\
7993 ++ "[INAT_LSTPFX_MAX + 1] = {"
7994 ++ for (i = 0; i < ggid; i++)
7995 ++ for (j = 0; j < max_lprefix; j++)
7996 ++ if (gtable[i,j])
7997 ++ print " ["i"]["j"] = "gtable[i,j]","
7998 ++ print "};\n"
7999 ++ # print AVX opcode map's array
8000 ++ print "/* AVX opcode map array */"
8001 ++ print "const insn_attr_t * const inat_avx_tables[X86_VEX_M_MAX + 1]"\
8002 ++ "[INAT_LSTPFX_MAX + 1] = {"
8003 ++ for (i = 0; i < gaid; i++)
8004 ++ for (j = 0; j < max_lprefix; j++)
8005 ++ if (atable[i,j])
8006 ++ print " ["i"]["j"] = "atable[i,j]","
8007 ++ print "};"
8008 ++}
8009 ++
8010 +diff --git a/tools/objtool/builtin-check.c b/tools/objtool/builtin-check.c
8011 +index a688a857a7ae..694abc628e9b 100644
8012 +--- a/tools/objtool/builtin-check.c
8013 ++++ b/tools/objtool/builtin-check.c
8014 +@@ -1,5 +1,5 @@
8015 + /*
8016 +- * Copyright (C) 2015 Josh Poimboeuf <jpoimboe@××××××.com>
8017 ++ * Copyright (C) 2015-2017 Josh Poimboeuf <jpoimboe@××××××.com>
8018 + *
8019 + * This program is free software; you can redistribute it and/or
8020 + * modify it under the terms of the GNU General Public License
8021 +@@ -25,1300 +25,35 @@
8022 + * For more information, see tools/objtool/Documentation/stack-validation.txt.
8023 + */
8024 +
8025 +-#include <string.h>
8026 +-#include <stdlib.h>
8027 + #include <subcmd/parse-options.h>
8028 +-
8029 + #include "builtin.h"
8030 +-#include "elf.h"
8031 +-#include "special.h"
8032 +-#include "arch.h"
8033 +-#include "warn.h"
8034 +-
8035 +-#include <linux/hashtable.h>
8036 +-
8037 +-#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
8038 +-
8039 +-#define STATE_FP_SAVED 0x1
8040 +-#define STATE_FP_SETUP 0x2
8041 +-#define STATE_FENTRY 0x4
8042 +-
8043 +-struct instruction {
8044 +- struct list_head list;
8045 +- struct hlist_node hash;
8046 +- struct section *sec;
8047 +- unsigned long offset;
8048 +- unsigned int len, state;
8049 +- unsigned char type;
8050 +- unsigned long immediate;
8051 +- bool alt_group, visited, ignore_alts;
8052 +- struct symbol *call_dest;
8053 +- struct instruction *jump_dest;
8054 +- struct list_head alts;
8055 +- struct symbol *func;
8056 +-};
8057 +-
8058 +-struct alternative {
8059 +- struct list_head list;
8060 +- struct instruction *insn;
8061 +-};
8062 +-
8063 +-struct objtool_file {
8064 +- struct elf *elf;
8065 +- struct list_head insn_list;
8066 +- DECLARE_HASHTABLE(insn_hash, 16);
8067 +- struct section *rodata, *whitelist;
8068 +- bool ignore_unreachables, c_file;
8069 +-};
8070 +-
8071 +-const char *objname;
8072 +-static bool nofp;
8073 +-
8074 +-static struct instruction *find_insn(struct objtool_file *file,
8075 +- struct section *sec, unsigned long offset)
8076 +-{
8077 +- struct instruction *insn;
8078 +-
8079 +- hash_for_each_possible(file->insn_hash, insn, hash, offset)
8080 +- if (insn->sec == sec && insn->offset == offset)
8081 +- return insn;
8082 +-
8083 +- return NULL;
8084 +-}
8085 +-
8086 +-static struct instruction *next_insn_same_sec(struct objtool_file *file,
8087 +- struct instruction *insn)
8088 +-{
8089 +- struct instruction *next = list_next_entry(insn, list);
8090 +-
8091 +- if (&next->list == &file->insn_list || next->sec != insn->sec)
8092 +- return NULL;
8093 +-
8094 +- return next;
8095 +-}
8096 +-
8097 +-static bool gcov_enabled(struct objtool_file *file)
8098 +-{
8099 +- struct section *sec;
8100 +- struct symbol *sym;
8101 +-
8102 +- list_for_each_entry(sec, &file->elf->sections, list)
8103 +- list_for_each_entry(sym, &sec->symbol_list, list)
8104 +- if (!strncmp(sym->name, "__gcov_.", 8))
8105 +- return true;
8106 +-
8107 +- return false;
8108 +-}
8109 +-
8110 +-#define for_each_insn(file, insn) \
8111 +- list_for_each_entry(insn, &file->insn_list, list)
8112 +-
8113 +-#define func_for_each_insn(file, func, insn) \
8114 +- for (insn = find_insn(file, func->sec, func->offset); \
8115 +- insn && &insn->list != &file->insn_list && \
8116 +- insn->sec == func->sec && \
8117 +- insn->offset < func->offset + func->len; \
8118 +- insn = list_next_entry(insn, list))
8119 +-
8120 +-#define func_for_each_insn_continue_reverse(file, func, insn) \
8121 +- for (insn = list_prev_entry(insn, list); \
8122 +- &insn->list != &file->insn_list && \
8123 +- insn->sec == func->sec && insn->offset >= func->offset; \
8124 +- insn = list_prev_entry(insn, list))
8125 +-
8126 +-#define sec_for_each_insn_from(file, insn) \
8127 +- for (; insn; insn = next_insn_same_sec(file, insn))
8128 +-
8129 +-
8130 +-/*
8131 +- * Check if the function has been manually whitelisted with the
8132 +- * STACK_FRAME_NON_STANDARD macro, or if it should be automatically whitelisted
8133 +- * due to its use of a context switching instruction.
8134 +- */
8135 +-static bool ignore_func(struct objtool_file *file, struct symbol *func)
8136 +-{
8137 +- struct rela *rela;
8138 +- struct instruction *insn;
8139 +-
8140 +- /* check for STACK_FRAME_NON_STANDARD */
8141 +- if (file->whitelist && file->whitelist->rela)
8142 +- list_for_each_entry(rela, &file->whitelist->rela->rela_list, list) {
8143 +- if (rela->sym->type == STT_SECTION &&
8144 +- rela->sym->sec == func->sec &&
8145 +- rela->addend == func->offset)
8146 +- return true;
8147 +- if (rela->sym->type == STT_FUNC && rela->sym == func)
8148 +- return true;
8149 +- }
8150 +-
8151 +- /* check if it has a context switching instruction */
8152 +- func_for_each_insn(file, func, insn)
8153 +- if (insn->type == INSN_CONTEXT_SWITCH)
8154 +- return true;
8155 +-
8156 +- return false;
8157 +-}
8158 +-
8159 +-/*
8160 +- * This checks to see if the given function is a "noreturn" function.
8161 +- *
8162 +- * For global functions which are outside the scope of this object file, we
8163 +- * have to keep a manual list of them.
8164 +- *
8165 +- * For local functions, we have to detect them manually by simply looking for
8166 +- * the lack of a return instruction.
8167 +- *
8168 +- * Returns:
8169 +- * -1: error
8170 +- * 0: no dead end
8171 +- * 1: dead end
8172 +- */
8173 +-static int __dead_end_function(struct objtool_file *file, struct symbol *func,
8174 +- int recursion)
8175 +-{
8176 +- int i;
8177 +- struct instruction *insn;
8178 +- bool empty = true;
8179 +-
8180 +- /*
8181 +- * Unfortunately these have to be hard coded because the noreturn
8182 +- * attribute isn't provided in ELF data.
8183 +- */
8184 +- static const char * const global_noreturns[] = {
8185 +- "__stack_chk_fail",
8186 +- "panic",
8187 +- "do_exit",
8188 +- "do_task_dead",
8189 +- "__module_put_and_exit",
8190 +- "complete_and_exit",
8191 +- "kvm_spurious_fault",
8192 +- "__reiserfs_panic",
8193 +- "lbug_with_loc"
8194 +- };
8195 +-
8196 +- if (func->bind == STB_WEAK)
8197 +- return 0;
8198 +-
8199 +- if (func->bind == STB_GLOBAL)
8200 +- for (i = 0; i < ARRAY_SIZE(global_noreturns); i++)
8201 +- if (!strcmp(func->name, global_noreturns[i]))
8202 +- return 1;
8203 +-
8204 +- if (!func->sec)
8205 +- return 0;
8206 +-
8207 +- func_for_each_insn(file, func, insn) {
8208 +- empty = false;
8209 +-
8210 +- if (insn->type == INSN_RETURN)
8211 +- return 0;
8212 +- }
8213 +-
8214 +- if (empty)
8215 +- return 0;
8216 +-
8217 +- /*
8218 +- * A function can have a sibling call instead of a return. In that
8219 +- * case, the function's dead-end status depends on whether the target
8220 +- * of the sibling call returns.
8221 +- */
8222 +- func_for_each_insn(file, func, insn) {
8223 +- if (insn->sec != func->sec ||
8224 +- insn->offset >= func->offset + func->len)
8225 +- break;
8226 +-
8227 +- if (insn->type == INSN_JUMP_UNCONDITIONAL) {
8228 +- struct instruction *dest = insn->jump_dest;
8229 +- struct symbol *dest_func;
8230 +-
8231 +- if (!dest)
8232 +- /* sibling call to another file */
8233 +- return 0;
8234 +-
8235 +- if (dest->sec != func->sec ||
8236 +- dest->offset < func->offset ||
8237 +- dest->offset >= func->offset + func->len) {
8238 +- /* local sibling call */
8239 +- dest_func = find_symbol_by_offset(dest->sec,
8240 +- dest->offset);
8241 +- if (!dest_func)
8242 +- continue;
8243 +-
8244 +- if (recursion == 5) {
8245 +- WARN_FUNC("infinite recursion (objtool bug!)",
8246 +- dest->sec, dest->offset);
8247 +- return -1;
8248 +- }
8249 +-
8250 +- return __dead_end_function(file, dest_func,
8251 +- recursion + 1);
8252 +- }
8253 +- }
8254 +-
8255 +- if (insn->type == INSN_JUMP_DYNAMIC && list_empty(&insn->alts))
8256 +- /* sibling call */
8257 +- return 0;
8258 +- }
8259 +-
8260 +- return 1;
8261 +-}
8262 +-
8263 +-static int dead_end_function(struct objtool_file *file, struct symbol *func)
8264 +-{
8265 +- return __dead_end_function(file, func, 0);
8266 +-}
8267 +-
8268 +-/*
8269 +- * Call the arch-specific instruction decoder for all the instructions and add
8270 +- * them to the global instruction list.
8271 +- */
8272 +-static int decode_instructions(struct objtool_file *file)
8273 +-{
8274 +- struct section *sec;
8275 +- struct symbol *func;
8276 +- unsigned long offset;
8277 +- struct instruction *insn;
8278 +- int ret;
8279 +-
8280 +- list_for_each_entry(sec, &file->elf->sections, list) {
8281 +-
8282 +- if (!(sec->sh.sh_flags & SHF_EXECINSTR))
8283 +- continue;
8284 +-
8285 +- for (offset = 0; offset < sec->len; offset += insn->len) {
8286 +- insn = malloc(sizeof(*insn));
8287 +- memset(insn, 0, sizeof(*insn));
8288 +-
8289 +- INIT_LIST_HEAD(&insn->alts);
8290 +- insn->sec = sec;
8291 +- insn->offset = offset;
8292 +-
8293 +- ret = arch_decode_instruction(file->elf, sec, offset,
8294 +- sec->len - offset,
8295 +- &insn->len, &insn->type,
8296 +- &insn->immediate);
8297 +- if (ret)
8298 +- return ret;
8299 +-
8300 +- if (!insn->type || insn->type > INSN_LAST) {
8301 +- WARN_FUNC("invalid instruction type %d",
8302 +- insn->sec, insn->offset, insn->type);
8303 +- return -1;
8304 +- }
8305 +-
8306 +- hash_add(file->insn_hash, &insn->hash, insn->offset);
8307 +- list_add_tail(&insn->list, &file->insn_list);
8308 +- }
8309 +-
8310 +- list_for_each_entry(func, &sec->symbol_list, list) {
8311 +- if (func->type != STT_FUNC)
8312 +- continue;
8313 +-
8314 +- if (!find_insn(file, sec, func->offset)) {
8315 +- WARN("%s(): can't find starting instruction",
8316 +- func->name);
8317 +- return -1;
8318 +- }
8319 +-
8320 +- func_for_each_insn(file, func, insn)
8321 +- if (!insn->func)
8322 +- insn->func = func;
8323 +- }
8324 +- }
8325 +-
8326 +- return 0;
8327 +-}
8328 +-
8329 +-/*
8330 +- * Warnings shouldn't be reported for ignored functions.
8331 +- */
8332 +-static void add_ignores(struct objtool_file *file)
8333 +-{
8334 +- struct instruction *insn;
8335 +- struct section *sec;
8336 +- struct symbol *func;
8337 +-
8338 +- list_for_each_entry(sec, &file->elf->sections, list) {
8339 +- list_for_each_entry(func, &sec->symbol_list, list) {
8340 +- if (func->type != STT_FUNC)
8341 +- continue;
8342 +-
8343 +- if (!ignore_func(file, func))
8344 +- continue;
8345 +-
8346 +- func_for_each_insn(file, func, insn)
8347 +- insn->visited = true;
8348 +- }
8349 +- }
8350 +-}
8351 +-
8352 +-/*
8353 +- * FIXME: For now, just ignore any alternatives which add retpolines. This is
8354 +- * a temporary hack, as it doesn't allow ORC to unwind from inside a retpoline.
8355 +- * But it at least allows objtool to understand the control flow *around* the
8356 +- * retpoline.
8357 +- */
8358 +-static int add_nospec_ignores(struct objtool_file *file)
8359 +-{
8360 +- struct section *sec;
8361 +- struct rela *rela;
8362 +- struct instruction *insn;
8363 +-
8364 +- sec = find_section_by_name(file->elf, ".rela.discard.nospec");
8365 +- if (!sec)
8366 +- return 0;
8367 +-
8368 +- list_for_each_entry(rela, &sec->rela_list, list) {
8369 +- if (rela->sym->type != STT_SECTION) {
8370 +- WARN("unexpected relocation symbol type in %s", sec->name);
8371 +- return -1;
8372 +- }
8373 +-
8374 +- insn = find_insn(file, rela->sym->sec, rela->addend);
8375 +- if (!insn) {
8376 +- WARN("bad .discard.nospec entry");
8377 +- return -1;
8378 +- }
8379 +-
8380 +- insn->ignore_alts = true;
8381 +- }
8382 +-
8383 +- return 0;
8384 +-}
8385 +-
8386 +-/*
8387 +- * Find the destination instructions for all jumps.
8388 +- */
8389 +-static int add_jump_destinations(struct objtool_file *file)
8390 +-{
8391 +- struct instruction *insn;
8392 +- struct rela *rela;
8393 +- struct section *dest_sec;
8394 +- unsigned long dest_off;
8395 +-
8396 +- for_each_insn(file, insn) {
8397 +- if (insn->type != INSN_JUMP_CONDITIONAL &&
8398 +- insn->type != INSN_JUMP_UNCONDITIONAL)
8399 +- continue;
8400 +-
8401 +- /* skip ignores */
8402 +- if (insn->visited)
8403 +- continue;
8404 +-
8405 +- rela = find_rela_by_dest_range(insn->sec, insn->offset,
8406 +- insn->len);
8407 +- if (!rela) {
8408 +- dest_sec = insn->sec;
8409 +- dest_off = insn->offset + insn->len + insn->immediate;
8410 +- } else if (rela->sym->type == STT_SECTION) {
8411 +- dest_sec = rela->sym->sec;
8412 +- dest_off = rela->addend + 4;
8413 +- } else if (rela->sym->sec->idx) {
8414 +- dest_sec = rela->sym->sec;
8415 +- dest_off = rela->sym->sym.st_value + rela->addend + 4;
8416 +- } else if (strstr(rela->sym->name, "_indirect_thunk_")) {
8417 +- /*
8418 +- * Retpoline jumps are really dynamic jumps in
8419 +- * disguise, so convert them accordingly.
8420 +- */
8421 +- insn->type = INSN_JUMP_DYNAMIC;
8422 +- continue;
8423 +- } else {
8424 +- /* sibling call */
8425 +- insn->jump_dest = 0;
8426 +- continue;
8427 +- }
8428 +-
8429 +- insn->jump_dest = find_insn(file, dest_sec, dest_off);
8430 +- if (!insn->jump_dest) {
8431 +-
8432 +- /*
8433 +- * This is a special case where an alt instruction
8434 +- * jumps past the end of the section. These are
8435 +- * handled later in handle_group_alt().
8436 +- */
8437 +- if (!strcmp(insn->sec->name, ".altinstr_replacement"))
8438 +- continue;
8439 +-
8440 +- WARN_FUNC("can't find jump dest instruction at %s+0x%lx",
8441 +- insn->sec, insn->offset, dest_sec->name,
8442 +- dest_off);
8443 +- return -1;
8444 +- }
8445 +- }
8446 +-
8447 +- return 0;
8448 +-}
8449 +-
8450 +-/*
8451 +- * Find the destination instructions for all calls.
8452 +- */
8453 +-static int add_call_destinations(struct objtool_file *file)
8454 +-{
8455 +- struct instruction *insn;
8456 +- unsigned long dest_off;
8457 +- struct rela *rela;
8458 +-
8459 +- for_each_insn(file, insn) {
8460 +- if (insn->type != INSN_CALL)
8461 +- continue;
8462 +-
8463 +- rela = find_rela_by_dest_range(insn->sec, insn->offset,
8464 +- insn->len);
8465 +- if (!rela) {
8466 +- dest_off = insn->offset + insn->len + insn->immediate;
8467 +- insn->call_dest = find_symbol_by_offset(insn->sec,
8468 +- dest_off);
8469 +- /*
8470 +- * FIXME: Thanks to retpolines, it's now considered
8471 +- * normal for a function to call within itself. So
8472 +- * disable this warning for now.
8473 +- */
8474 +-#if 0
8475 +- if (!insn->call_dest) {
8476 +- WARN_FUNC("can't find call dest symbol at offset 0x%lx",
8477 +- insn->sec, insn->offset, dest_off);
8478 +- return -1;
8479 +- }
8480 +-#endif
8481 +- } else if (rela->sym->type == STT_SECTION) {
8482 +- insn->call_dest = find_symbol_by_offset(rela->sym->sec,
8483 +- rela->addend+4);
8484 +- if (!insn->call_dest ||
8485 +- insn->call_dest->type != STT_FUNC) {
8486 +- WARN_FUNC("can't find call dest symbol at %s+0x%x",
8487 +- insn->sec, insn->offset,
8488 +- rela->sym->sec->name,
8489 +- rela->addend + 4);
8490 +- return -1;
8491 +- }
8492 +- } else
8493 +- insn->call_dest = rela->sym;
8494 +- }
8495 +-
8496 +- return 0;
8497 +-}
8498 +-
8499 +-/*
8500 +- * The .alternatives section requires some extra special care, over and above
8501 +- * what other special sections require:
8502 +- *
8503 +- * 1. Because alternatives are patched in-place, we need to insert a fake jump
8504 +- * instruction at the end so that validate_branch() skips all the original
8505 +- * replaced instructions when validating the new instruction path.
8506 +- *
8507 +- * 2. An added wrinkle is that the new instruction length might be zero. In
8508 +- * that case the old instructions are replaced with noops. We simulate that
8509 +- * by creating a fake jump as the only new instruction.
8510 +- *
8511 +- * 3. In some cases, the alternative section includes an instruction which
8512 +- * conditionally jumps to the _end_ of the entry. We have to modify these
8513 +- * jumps' destinations to point back to .text rather than the end of the
8514 +- * entry in .altinstr_replacement.
8515 +- *
8516 +- * 4. It has been requested that we don't validate the !POPCNT feature path
8517 +- * which is a "very very small percentage of machines".
8518 +- */
8519 +-static int handle_group_alt(struct objtool_file *file,
8520 +- struct special_alt *special_alt,
8521 +- struct instruction *orig_insn,
8522 +- struct instruction **new_insn)
8523 +-{
8524 +- struct instruction *last_orig_insn, *last_new_insn, *insn, *fake_jump;
8525 +- unsigned long dest_off;
8526 +-
8527 +- last_orig_insn = NULL;
8528 +- insn = orig_insn;
8529 +- sec_for_each_insn_from(file, insn) {
8530 +- if (insn->offset >= special_alt->orig_off + special_alt->orig_len)
8531 +- break;
8532 +-
8533 +- if (special_alt->skip_orig)
8534 +- insn->type = INSN_NOP;
8535 +-
8536 +- insn->alt_group = true;
8537 +- last_orig_insn = insn;
8538 +- }
8539 +-
8540 +- if (!next_insn_same_sec(file, last_orig_insn)) {
8541 +- WARN("%s: don't know how to handle alternatives at end of section",
8542 +- special_alt->orig_sec->name);
8543 +- return -1;
8544 +- }
8545 +-
8546 +- fake_jump = malloc(sizeof(*fake_jump));
8547 +- if (!fake_jump) {
8548 +- WARN("malloc failed");
8549 +- return -1;
8550 +- }
8551 +- memset(fake_jump, 0, sizeof(*fake_jump));
8552 +- INIT_LIST_HEAD(&fake_jump->alts);
8553 +- fake_jump->sec = special_alt->new_sec;
8554 +- fake_jump->offset = -1;
8555 +- fake_jump->type = INSN_JUMP_UNCONDITIONAL;
8556 +- fake_jump->jump_dest = list_next_entry(last_orig_insn, list);
8557 +-
8558 +- if (!special_alt->new_len) {
8559 +- *new_insn = fake_jump;
8560 +- return 0;
8561 +- }
8562 +-
8563 +- last_new_insn = NULL;
8564 +- insn = *new_insn;
8565 +- sec_for_each_insn_from(file, insn) {
8566 +- if (insn->offset >= special_alt->new_off + special_alt->new_len)
8567 +- break;
8568 +-
8569 +- last_new_insn = insn;
8570 +-
8571 +- if (insn->type != INSN_JUMP_CONDITIONAL &&
8572 +- insn->type != INSN_JUMP_UNCONDITIONAL)
8573 +- continue;
8574 +-
8575 +- if (!insn->immediate)
8576 +- continue;
8577 +-
8578 +- dest_off = insn->offset + insn->len + insn->immediate;
8579 +- if (dest_off == special_alt->new_off + special_alt->new_len)
8580 +- insn->jump_dest = fake_jump;
8581 +-
8582 +- if (!insn->jump_dest) {
8583 +- WARN_FUNC("can't find alternative jump destination",
8584 +- insn->sec, insn->offset);
8585 +- return -1;
8586 +- }
8587 +- }
8588 +-
8589 +- if (!last_new_insn) {
8590 +- WARN_FUNC("can't find last new alternative instruction",
8591 +- special_alt->new_sec, special_alt->new_off);
8592 +- return -1;
8593 +- }
8594 +-
8595 +- list_add(&fake_jump->list, &last_new_insn->list);
8596 +-
8597 +- return 0;
8598 +-}
8599 +-
8600 +-/*
8601 +- * A jump table entry can either convert a nop to a jump or a jump to a nop.
8602 +- * If the original instruction is a jump, make the alt entry an effective nop
8603 +- * by just skipping the original instruction.
8604 +- */
8605 +-static int handle_jump_alt(struct objtool_file *file,
8606 +- struct special_alt *special_alt,
8607 +- struct instruction *orig_insn,
8608 +- struct instruction **new_insn)
8609 +-{
8610 +- if (orig_insn->type == INSN_NOP)
8611 +- return 0;
8612 +-
8613 +- if (orig_insn->type != INSN_JUMP_UNCONDITIONAL) {
8614 +- WARN_FUNC("unsupported instruction at jump label",
8615 +- orig_insn->sec, orig_insn->offset);
8616 +- return -1;
8617 +- }
8618 +-
8619 +- *new_insn = list_next_entry(orig_insn, list);
8620 +- return 0;
8621 +-}
8622 +-
8623 +-/*
8624 +- * Read all the special sections which have alternate instructions which can be
8625 +- * patched in or redirected to at runtime. Each instruction having alternate
8626 +- * instruction(s) has them added to its insn->alts list, which will be
8627 +- * traversed in validate_branch().
8628 +- */
8629 +-static int add_special_section_alts(struct objtool_file *file)
8630 +-{
8631 +- struct list_head special_alts;
8632 +- struct instruction *orig_insn, *new_insn;
8633 +- struct special_alt *special_alt, *tmp;
8634 +- struct alternative *alt;
8635 +- int ret;
8636 +-
8637 +- ret = special_get_alts(file->elf, &special_alts);
8638 +- if (ret)
8639 +- return ret;
8640 +-
8641 +- list_for_each_entry_safe(special_alt, tmp, &special_alts, list) {
8642 +-
8643 +- orig_insn = find_insn(file, special_alt->orig_sec,
8644 +- special_alt->orig_off);
8645 +- if (!orig_insn) {
8646 +- WARN_FUNC("special: can't find orig instruction",
8647 +- special_alt->orig_sec, special_alt->orig_off);
8648 +- ret = -1;
8649 +- goto out;
8650 +- }
8651 +-
8652 +- /* Ignore retpoline alternatives. */
8653 +- if (orig_insn->ignore_alts)
8654 +- continue;
8655 +-
8656 +- new_insn = NULL;
8657 +- if (!special_alt->group || special_alt->new_len) {
8658 +- new_insn = find_insn(file, special_alt->new_sec,
8659 +- special_alt->new_off);
8660 +- if (!new_insn) {
8661 +- WARN_FUNC("special: can't find new instruction",
8662 +- special_alt->new_sec,
8663 +- special_alt->new_off);
8664 +- ret = -1;
8665 +- goto out;
8666 +- }
8667 +- }
8668 ++#include "check.h"
8669 +
8670 +- if (special_alt->group) {
8671 +- ret = handle_group_alt(file, special_alt, orig_insn,
8672 +- &new_insn);
8673 +- if (ret)
8674 +- goto out;
8675 +- } else if (special_alt->jump_or_nop) {
8676 +- ret = handle_jump_alt(file, special_alt, orig_insn,
8677 +- &new_insn);
8678 +- if (ret)
8679 +- goto out;
8680 +- }
8681 ++bool no_fp, no_unreachable, retpoline, module;
8682 +
8683 +- alt = malloc(sizeof(*alt));
8684 +- if (!alt) {
8685 +- WARN("malloc failed");
8686 +- ret = -1;
8687 +- goto out;
8688 +- }
8689 +-
8690 +- alt->insn = new_insn;
8691 +- list_add_tail(&alt->list, &orig_insn->alts);
8692 +-
8693 +- list_del(&special_alt->list);
8694 +- free(special_alt);
8695 +- }
8696 +-
8697 +-out:
8698 +- return ret;
8699 +-}
8700 +-
8701 +-static int add_switch_table(struct objtool_file *file, struct symbol *func,
8702 +- struct instruction *insn, struct rela *table,
8703 +- struct rela *next_table)
8704 +-{
8705 +- struct rela *rela = table;
8706 +- struct instruction *alt_insn;
8707 +- struct alternative *alt;
8708 +-
8709 +- list_for_each_entry_from(rela, &file->rodata->rela->rela_list, list) {
8710 +- if (rela == next_table)
8711 +- break;
8712 +-
8713 +- if (rela->sym->sec != insn->sec ||
8714 +- rela->addend <= func->offset ||
8715 +- rela->addend >= func->offset + func->len)
8716 +- break;
8717 +-
8718 +- alt_insn = find_insn(file, insn->sec, rela->addend);
8719 +- if (!alt_insn) {
8720 +- WARN("%s: can't find instruction at %s+0x%x",
8721 +- file->rodata->rela->name, insn->sec->name,
8722 +- rela->addend);
8723 +- return -1;
8724 +- }
8725 +-
8726 +- alt = malloc(sizeof(*alt));
8727 +- if (!alt) {
8728 +- WARN("malloc failed");
8729 +- return -1;
8730 +- }
8731 +-
8732 +- alt->insn = alt_insn;
8733 +- list_add_tail(&alt->list, &insn->alts);
8734 +- }
8735 +-
8736 +- return 0;
8737 +-}
8738 +-
8739 +-/*
8740 +- * find_switch_table() - Given a dynamic jump, find the switch jump table in
8741 +- * .rodata associated with it.
8742 +- *
8743 +- * There are 3 basic patterns:
8744 +- *
8745 +- * 1. jmpq *[rodata addr](,%reg,8)
8746 +- *
8747 +- * This is the most common case by far. It jumps to an address in a simple
8748 +- * jump table which is stored in .rodata.
8749 +- *
8750 +- * 2. jmpq *[rodata addr](%rip)
8751 +- *
8752 +- * This is caused by a rare GCC quirk, currently only seen in three driver
8753 +- * functions in the kernel, only with certain obscure non-distro configs.
8754 +- *
8755 +- * As part of an optimization, GCC makes a copy of an existing switch jump
8756 +- * table, modifies it, and then hard-codes the jump (albeit with an indirect
8757 +- * jump) to use a single entry in the table. The rest of the jump table and
8758 +- * some of its jump targets remain as dead code.
8759 +- *
8760 +- * In such a case we can just crudely ignore all unreachable instruction
8761 +- * warnings for the entire object file. Ideally we would just ignore them
8762 +- * for the function, but that would require redesigning the code quite a
8763 +- * bit. And honestly that's just not worth doing: unreachable instruction
8764 +- * warnings are of questionable value anyway, and this is such a rare issue.
8765 +- *
8766 +- * 3. mov [rodata addr],%reg1
8767 +- * ... some instructions ...
8768 +- * jmpq *(%reg1,%reg2,8)
8769 +- *
8770 +- * This is a fairly uncommon pattern which is new for GCC 6. As of this
8771 +- * writing, there are 11 occurrences of it in the allmodconfig kernel.
8772 +- *
8773 +- * TODO: Once we have DWARF CFI and smarter instruction decoding logic,
8774 +- * ensure the same register is used in the mov and jump instructions.
8775 +- */
8776 +-static struct rela *find_switch_table(struct objtool_file *file,
8777 +- struct symbol *func,
8778 +- struct instruction *insn)
8779 +-{
8780 +- struct rela *text_rela, *rodata_rela;
8781 +- struct instruction *orig_insn = insn;
8782 +-
8783 +- text_rela = find_rela_by_dest_range(insn->sec, insn->offset, insn->len);
8784 +- if (text_rela && text_rela->sym == file->rodata->sym) {
8785 +- /* case 1 */
8786 +- rodata_rela = find_rela_by_dest(file->rodata,
8787 +- text_rela->addend);
8788 +- if (rodata_rela)
8789 +- return rodata_rela;
8790 +-
8791 +- /* case 2 */
8792 +- rodata_rela = find_rela_by_dest(file->rodata,
8793 +- text_rela->addend + 4);
8794 +- if (!rodata_rela)
8795 +- return NULL;
8796 +- file->ignore_unreachables = true;
8797 +- return rodata_rela;
8798 +- }
8799 +-
8800 +- /* case 3 */
8801 +- func_for_each_insn_continue_reverse(file, func, insn) {
8802 +- if (insn->type == INSN_JUMP_DYNAMIC)
8803 +- break;
8804 +-
8805 +- /* allow small jumps within the range */
8806 +- if (insn->type == INSN_JUMP_UNCONDITIONAL &&
8807 +- insn->jump_dest &&
8808 +- (insn->jump_dest->offset <= insn->offset ||
8809 +- insn->jump_dest->offset > orig_insn->offset))
8810 +- break;
8811 +-
8812 +- /* look for a relocation which references .rodata */
8813 +- text_rela = find_rela_by_dest_range(insn->sec, insn->offset,
8814 +- insn->len);
8815 +- if (!text_rela || text_rela->sym != file->rodata->sym)
8816 +- continue;
8817 +-
8818 +- /*
8819 +- * Make sure the .rodata address isn't associated with a
8820 +- * symbol. gcc jump tables are anonymous data.
8821 +- */
8822 +- if (find_symbol_containing(file->rodata, text_rela->addend))
8823 +- continue;
8824 +-
8825 +- return find_rela_by_dest(file->rodata, text_rela->addend);
8826 +- }
8827 +-
8828 +- return NULL;
8829 +-}
8830 +-
8831 +-static int add_func_switch_tables(struct objtool_file *file,
8832 +- struct symbol *func)
8833 +-{
8834 +- struct instruction *insn, *prev_jump = NULL;
8835 +- struct rela *rela, *prev_rela = NULL;
8836 +- int ret;
8837 +-
8838 +- func_for_each_insn(file, func, insn) {
8839 +- if (insn->type != INSN_JUMP_DYNAMIC)
8840 +- continue;
8841 +-
8842 +- rela = find_switch_table(file, func, insn);
8843 +- if (!rela)
8844 +- continue;
8845 +-
8846 +- /*
8847 +- * We found a switch table, but we don't know yet how big it
8848 +- * is. Don't add it until we reach the end of the function or
8849 +- * the beginning of another switch table in the same function.
8850 +- */
8851 +- if (prev_jump) {
8852 +- ret = add_switch_table(file, func, prev_jump, prev_rela,
8853 +- rela);
8854 +- if (ret)
8855 +- return ret;
8856 +- }
8857 +-
8858 +- prev_jump = insn;
8859 +- prev_rela = rela;
8860 +- }
8861 +-
8862 +- if (prev_jump) {
8863 +- ret = add_switch_table(file, func, prev_jump, prev_rela, NULL);
8864 +- if (ret)
8865 +- return ret;
8866 +- }
8867 +-
8868 +- return 0;
8869 +-}
8870 +-
8871 +-/*
8872 +- * For some switch statements, gcc generates a jump table in the .rodata
8873 +- * section which contains a list of addresses within the function to jump to.
8874 +- * This finds these jump tables and adds them to the insn->alts lists.
8875 +- */
8876 +-static int add_switch_table_alts(struct objtool_file *file)
8877 +-{
8878 +- struct section *sec;
8879 +- struct symbol *func;
8880 +- int ret;
8881 +-
8882 +- if (!file->rodata || !file->rodata->rela)
8883 +- return 0;
8884 +-
8885 +- list_for_each_entry(sec, &file->elf->sections, list) {
8886 +- list_for_each_entry(func, &sec->symbol_list, list) {
8887 +- if (func->type != STT_FUNC)
8888 +- continue;
8889 +-
8890 +- ret = add_func_switch_tables(file, func);
8891 +- if (ret)
8892 +- return ret;
8893 +- }
8894 +- }
8895 +-
8896 +- return 0;
8897 +-}
8898 +-
8899 +-static int decode_sections(struct objtool_file *file)
8900 +-{
8901 +- int ret;
8902 +-
8903 +- ret = decode_instructions(file);
8904 +- if (ret)
8905 +- return ret;
8906 +-
8907 +- add_ignores(file);
8908 +-
8909 +- ret = add_nospec_ignores(file);
8910 +- if (ret)
8911 +- return ret;
8912 +-
8913 +- ret = add_jump_destinations(file);
8914 +- if (ret)
8915 +- return ret;
8916 +-
8917 +- ret = add_call_destinations(file);
8918 +- if (ret)
8919 +- return ret;
8920 +-
8921 +- ret = add_special_section_alts(file);
8922 +- if (ret)
8923 +- return ret;
8924 +-
8925 +- ret = add_switch_table_alts(file);
8926 +- if (ret)
8927 +- return ret;
8928 +-
8929 +- return 0;
8930 +-}
8931 +-
8932 +-static bool is_fentry_call(struct instruction *insn)
8933 +-{
8934 +- if (insn->type == INSN_CALL &&
8935 +- insn->call_dest->type == STT_NOTYPE &&
8936 +- !strcmp(insn->call_dest->name, "__fentry__"))
8937 +- return true;
8938 +-
8939 +- return false;
8940 +-}
8941 +-
8942 +-static bool has_modified_stack_frame(struct instruction *insn)
8943 +-{
8944 +- return (insn->state & STATE_FP_SAVED) ||
8945 +- (insn->state & STATE_FP_SETUP);
8946 +-}
8947 +-
8948 +-static bool has_valid_stack_frame(struct instruction *insn)
8949 +-{
8950 +- return (insn->state & STATE_FP_SAVED) &&
8951 +- (insn->state & STATE_FP_SETUP);
8952 +-}
8953 +-
8954 +-static unsigned int frame_state(unsigned long state)
8955 +-{
8956 +- return (state & (STATE_FP_SAVED | STATE_FP_SETUP));
8957 +-}
8958 +-
8959 +-/*
8960 +- * Follow the branch starting at the given instruction, and recursively follow
8961 +- * any other branches (jumps). Meanwhile, track the frame pointer state at
8962 +- * each instruction and validate all the rules described in
8963 +- * tools/objtool/Documentation/stack-validation.txt.
8964 +- */
8965 +-static int validate_branch(struct objtool_file *file,
8966 +- struct instruction *first, unsigned char first_state)
8967 +-{
8968 +- struct alternative *alt;
8969 +- struct instruction *insn;
8970 +- struct section *sec;
8971 +- struct symbol *func = NULL;
8972 +- unsigned char state;
8973 +- int ret;
8974 +-
8975 +- insn = first;
8976 +- sec = insn->sec;
8977 +- state = first_state;
8978 +-
8979 +- if (insn->alt_group && list_empty(&insn->alts)) {
8980 +- WARN_FUNC("don't know how to handle branch to middle of alternative instruction group",
8981 +- sec, insn->offset);
8982 +- return 1;
8983 +- }
8984 +-
8985 +- while (1) {
8986 +- if (file->c_file && insn->func) {
8987 +- if (func && func != insn->func) {
8988 +- WARN("%s() falls through to next function %s()",
8989 +- func->name, insn->func->name);
8990 +- return 1;
8991 +- }
8992 +-
8993 +- func = insn->func;
8994 +- }
8995 +-
8996 +- if (insn->visited) {
8997 +- if (frame_state(insn->state) != frame_state(state)) {
8998 +- WARN_FUNC("frame pointer state mismatch",
8999 +- sec, insn->offset);
9000 +- return 1;
9001 +- }
9002 +-
9003 +- return 0;
9004 +- }
9005 +-
9006 +- insn->visited = true;
9007 +- insn->state = state;
9008 +-
9009 +- list_for_each_entry(alt, &insn->alts, list) {
9010 +- ret = validate_branch(file, alt->insn, state);
9011 +- if (ret)
9012 +- return 1;
9013 +- }
9014 +-
9015 +- switch (insn->type) {
9016 +-
9017 +- case INSN_FP_SAVE:
9018 +- if (!nofp) {
9019 +- if (state & STATE_FP_SAVED) {
9020 +- WARN_FUNC("duplicate frame pointer save",
9021 +- sec, insn->offset);
9022 +- return 1;
9023 +- }
9024 +- state |= STATE_FP_SAVED;
9025 +- }
9026 +- break;
9027 +-
9028 +- case INSN_FP_SETUP:
9029 +- if (!nofp) {
9030 +- if (state & STATE_FP_SETUP) {
9031 +- WARN_FUNC("duplicate frame pointer setup",
9032 +- sec, insn->offset);
9033 +- return 1;
9034 +- }
9035 +- state |= STATE_FP_SETUP;
9036 +- }
9037 +- break;
9038 +-
9039 +- case INSN_FP_RESTORE:
9040 +- if (!nofp) {
9041 +- if (has_valid_stack_frame(insn))
9042 +- state &= ~STATE_FP_SETUP;
9043 +-
9044 +- state &= ~STATE_FP_SAVED;
9045 +- }
9046 +- break;
9047 +-
9048 +- case INSN_RETURN:
9049 +- if (!nofp && has_modified_stack_frame(insn)) {
9050 +- WARN_FUNC("return without frame pointer restore",
9051 +- sec, insn->offset);
9052 +- return 1;
9053 +- }
9054 +- return 0;
9055 +-
9056 +- case INSN_CALL:
9057 +- if (is_fentry_call(insn)) {
9058 +- state |= STATE_FENTRY;
9059 +- break;
9060 +- }
9061 +-
9062 +- ret = dead_end_function(file, insn->call_dest);
9063 +- if (ret == 1)
9064 +- return 0;
9065 +- if (ret == -1)
9066 +- return 1;
9067 +-
9068 +- /* fallthrough */
9069 +- case INSN_CALL_DYNAMIC:
9070 +- if (!nofp && !has_valid_stack_frame(insn)) {
9071 +- WARN_FUNC("call without frame pointer save/setup",
9072 +- sec, insn->offset);
9073 +- return 1;
9074 +- }
9075 +- break;
9076 +-
9077 +- case INSN_JUMP_CONDITIONAL:
9078 +- case INSN_JUMP_UNCONDITIONAL:
9079 +- if (insn->jump_dest) {
9080 +- ret = validate_branch(file, insn->jump_dest,
9081 +- state);
9082 +- if (ret)
9083 +- return 1;
9084 +- } else if (has_modified_stack_frame(insn)) {
9085 +- WARN_FUNC("sibling call from callable instruction with changed frame pointer",
9086 +- sec, insn->offset);
9087 +- return 1;
9088 +- } /* else it's a sibling call */
9089 +-
9090 +- if (insn->type == INSN_JUMP_UNCONDITIONAL)
9091 +- return 0;
9092 +-
9093 +- break;
9094 +-
9095 +- case INSN_JUMP_DYNAMIC:
9096 +- if (list_empty(&insn->alts) &&
9097 +- has_modified_stack_frame(insn)) {
9098 +- WARN_FUNC("sibling call from callable instruction with changed frame pointer",
9099 +- sec, insn->offset);
9100 +- return 1;
9101 +- }
9102 +-
9103 +- return 0;
9104 +-
9105 +- case INSN_BUG:
9106 +- return 0;
9107 +-
9108 +- default:
9109 +- break;
9110 +- }
9111 +-
9112 +- insn = next_insn_same_sec(file, insn);
9113 +- if (!insn) {
9114 +- WARN("%s: unexpected end of section", sec->name);
9115 +- return 1;
9116 +- }
9117 +- }
9118 +-
9119 +- return 0;
9120 +-}
9121 +-
9122 +-static bool is_kasan_insn(struct instruction *insn)
9123 +-{
9124 +- return (insn->type == INSN_CALL &&
9125 +- !strcmp(insn->call_dest->name, "__asan_handle_no_return"));
9126 +-}
9127 +-
9128 +-static bool is_ubsan_insn(struct instruction *insn)
9129 +-{
9130 +- return (insn->type == INSN_CALL &&
9131 +- !strcmp(insn->call_dest->name,
9132 +- "__ubsan_handle_builtin_unreachable"));
9133 +-}
9134 +-
9135 +-static bool ignore_unreachable_insn(struct symbol *func,
9136 +- struct instruction *insn)
9137 +-{
9138 +- int i;
9139 +-
9140 +- if (insn->type == INSN_NOP)
9141 +- return true;
9142 +-
9143 +- /*
9144 +- * Check if this (or a subsequent) instruction is related to
9145 +- * CONFIG_UBSAN or CONFIG_KASAN.
9146 +- *
9147 +- * End the search at 5 instructions to avoid going into the weeds.
9148 +- */
9149 +- for (i = 0; i < 5; i++) {
9150 +-
9151 +- if (is_kasan_insn(insn) || is_ubsan_insn(insn))
9152 +- return true;
9153 +-
9154 +- if (insn->type == INSN_JUMP_UNCONDITIONAL && insn->jump_dest) {
9155 +- insn = insn->jump_dest;
9156 +- continue;
9157 +- }
9158 +-
9159 +- if (insn->offset + insn->len >= func->offset + func->len)
9160 +- break;
9161 +- insn = list_next_entry(insn, list);
9162 +- }
9163 +-
9164 +- return false;
9165 +-}
9166 +-
9167 +-static int validate_functions(struct objtool_file *file)
9168 +-{
9169 +- struct section *sec;
9170 +- struct symbol *func;
9171 +- struct instruction *insn;
9172 +- int ret, warnings = 0;
9173 +-
9174 +- list_for_each_entry(sec, &file->elf->sections, list) {
9175 +- list_for_each_entry(func, &sec->symbol_list, list) {
9176 +- if (func->type != STT_FUNC)
9177 +- continue;
9178 +-
9179 +- insn = find_insn(file, sec, func->offset);
9180 +- if (!insn)
9181 +- continue;
9182 +-
9183 +- ret = validate_branch(file, insn, 0);
9184 +- warnings += ret;
9185 +- }
9186 +- }
9187 +-
9188 +- list_for_each_entry(sec, &file->elf->sections, list) {
9189 +- list_for_each_entry(func, &sec->symbol_list, list) {
9190 +- if (func->type != STT_FUNC)
9191 +- continue;
9192 +-
9193 +- func_for_each_insn(file, func, insn) {
9194 +- if (insn->visited)
9195 +- continue;
9196 +-
9197 +- insn->visited = true;
9198 +-
9199 +- if (file->ignore_unreachables || warnings ||
9200 +- ignore_unreachable_insn(func, insn))
9201 +- continue;
9202 +-
9203 +- /*
9204 +- * gcov produces a lot of unreachable
9205 +- * instructions. If we get an unreachable
9206 +- * warning and the file has gcov enabled, just
9207 +- * ignore it, and all other such warnings for
9208 +- * the file.
9209 +- */
9210 +- if (!file->ignore_unreachables &&
9211 +- gcov_enabled(file)) {
9212 +- file->ignore_unreachables = true;
9213 +- continue;
9214 +- }
9215 +-
9216 +- WARN_FUNC("function has unreachable instruction", insn->sec, insn->offset);
9217 +- warnings++;
9218 +- }
9219 +- }
9220 +- }
9221 +-
9222 +- return warnings;
9223 +-}
9224 +-
9225 +-static int validate_uncallable_instructions(struct objtool_file *file)
9226 +-{
9227 +- struct instruction *insn;
9228 +- int warnings = 0;
9229 +-
9230 +- for_each_insn(file, insn) {
9231 +- if (!insn->visited && insn->type == INSN_RETURN) {
9232 +-
9233 +- /*
9234 +- * Don't warn about call instructions in unvisited
9235 +- * retpoline alternatives.
9236 +- */
9237 +- if (!strcmp(insn->sec->name, ".altinstr_replacement"))
9238 +- continue;
9239 +-
9240 +- WARN_FUNC("return instruction outside of a callable function",
9241 +- insn->sec, insn->offset);
9242 +- warnings++;
9243 +- }
9244 +- }
9245 +-
9246 +- return warnings;
9247 +-}
9248 +-
9249 +-static void cleanup(struct objtool_file *file)
9250 +-{
9251 +- struct instruction *insn, *tmpinsn;
9252 +- struct alternative *alt, *tmpalt;
9253 +-
9254 +- list_for_each_entry_safe(insn, tmpinsn, &file->insn_list, list) {
9255 +- list_for_each_entry_safe(alt, tmpalt, &insn->alts, list) {
9256 +- list_del(&alt->list);
9257 +- free(alt);
9258 +- }
9259 +- list_del(&insn->list);
9260 +- hash_del(&insn->hash);
9261 +- free(insn);
9262 +- }
9263 +- elf_close(file->elf);
9264 +-}
9265 +-
9266 +-const char * const check_usage[] = {
9267 ++static const char * const check_usage[] = {
9268 + "objtool check [<options>] file.o",
9269 + NULL,
9270 + };
9271 +
9272 ++const struct option check_options[] = {
9273 ++ OPT_BOOLEAN('f', "no-fp", &no_fp, "Skip frame pointer validation"),
9274 ++ OPT_BOOLEAN('u', "no-unreachable", &no_unreachable, "Skip 'unreachable instruction' warnings"),
9275 ++ OPT_BOOLEAN('r', "retpoline", &retpoline, "Validate retpoline assumptions"),
9276 ++ OPT_BOOLEAN('m', "module", &module, "Indicates the object will be part of a kernel module"),
9277 ++ OPT_END(),
9278 ++};
9279 ++
9280 + int cmd_check(int argc, const char **argv)
9281 + {
9282 +- struct objtool_file file;
9283 +- int ret, warnings = 0;
9284 +-
9285 +- const struct option options[] = {
9286 +- OPT_BOOLEAN('f', "no-fp", &nofp, "Skip frame pointer validation"),
9287 +- OPT_END(),
9288 +- };
9289 ++ const char *objname;
9290 +
9291 +- argc = parse_options(argc, argv, options, check_usage, 0);
9292 ++ argc = parse_options(argc, argv, check_options, check_usage, 0);
9293 +
9294 + if (argc != 1)
9295 +- usage_with_options(check_usage, options);
9296 ++ usage_with_options(check_usage, check_options);
9297 +
9298 + objname = argv[0];
9299 +
9300 +- file.elf = elf_open(objname);
9301 +- if (!file.elf) {
9302 +- fprintf(stderr, "error reading elf file %s\n", objname);
9303 +- return 1;
9304 +- }
9305 +-
9306 +- INIT_LIST_HEAD(&file.insn_list);
9307 +- hash_init(file.insn_hash);
9308 +- file.whitelist = find_section_by_name(file.elf, ".discard.func_stack_frame_non_standard");
9309 +- file.rodata = find_section_by_name(file.elf, ".rodata");
9310 +- file.ignore_unreachables = false;
9311 +- file.c_file = find_section_by_name(file.elf, ".comment");
9312 +-
9313 +- ret = decode_sections(&file);
9314 +- if (ret < 0)
9315 +- goto out;
9316 +- warnings += ret;
9317 +-
9318 +- ret = validate_functions(&file);
9319 +- if (ret < 0)
9320 +- goto out;
9321 +- warnings += ret;
9322 +-
9323 +- ret = validate_uncallable_instructions(&file);
9324 +- if (ret < 0)
9325 +- goto out;
9326 +- warnings += ret;
9327 +-
9328 +-out:
9329 +- cleanup(&file);
9330 +-
9331 +- /* ignore warnings for now until we get all the code cleaned up */
9332 +- if (ret || warnings)
9333 +- return 0;
9334 +- return 0;
9335 ++ return check(objname, false);
9336 + }
9337 +diff --git a/tools/objtool/builtin-orc.c b/tools/objtool/builtin-orc.c
9338 +new file mode 100644
9339 +index 000000000000..77ea2b97117d
9340 +--- /dev/null
9341 ++++ b/tools/objtool/builtin-orc.c
9342 +@@ -0,0 +1,68 @@
9343 ++/*
9344 ++ * Copyright (C) 2017 Josh Poimboeuf <jpoimboe@××××××.com>
9345 ++ *
9346 ++ * This program is free software; you can redistribute it and/or
9347 ++ * modify it under the terms of the GNU General Public License
9348 ++ * as published by the Free Software Foundation; either version 2
9349 ++ * of the License, or (at your option) any later version.
9350 ++ *
9351 ++ * This program is distributed in the hope that it will be useful,
9352 ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
9353 ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9354 ++ * GNU General Public License for more details.
9355 ++ *
9356 ++ * You should have received a copy of the GNU General Public License
9357 ++ * along with this program; if not, see <http://www.gnu.org/licenses/>.
9358 ++ */
9359 ++
9360 ++/*
9361 ++ * objtool orc:
9362 ++ *
9363 ++ * This command analyzes a .o file and adds .orc_unwind and .orc_unwind_ip
9364 ++ * sections to it, which is used by the in-kernel ORC unwinder.
9365 ++ *
9366 ++ * This command is a superset of "objtool check".
9367 ++ */
9368 ++
9369 ++#include <string.h>
9370 ++#include "builtin.h"
9371 ++#include "check.h"
9372 ++
9373 ++
9374 ++static const char *orc_usage[] = {
9375 ++ "objtool orc generate [<options>] file.o",
9376 ++ "objtool orc dump file.o",
9377 ++ NULL,
9378 ++};
9379 ++
9380 ++int cmd_orc(int argc, const char **argv)
9381 ++{
9382 ++ const char *objname;
9383 ++
9384 ++ argc--; argv++;
9385 ++ if (argc <= 0)
9386 ++ usage_with_options(orc_usage, check_options);
9387 ++
9388 ++ if (!strncmp(argv[0], "gen", 3)) {
9389 ++ argc = parse_options(argc, argv, check_options, orc_usage, 0);
9390 ++ if (argc != 1)
9391 ++ usage_with_options(orc_usage, check_options);
9392 ++
9393 ++ objname = argv[0];
9394 ++
9395 ++ return check(objname, true);
9396 ++ }
9397 ++
9398 ++ if (!strcmp(argv[0], "dump")) {
9399 ++ if (argc != 2)
9400 ++ usage_with_options(orc_usage, check_options);
9401 ++
9402 ++ objname = argv[1];
9403 ++
9404 ++ return orc_dump(objname);
9405 ++ }
9406 ++
9407 ++ usage_with_options(orc_usage, check_options);
9408 ++
9409 ++ return 0;
9410 ++}
9411 +diff --git a/tools/objtool/builtin.h b/tools/objtool/builtin.h
9412 +index 34d2ba78a616..28ff40e19a14 100644
9413 +--- a/tools/objtool/builtin.h
9414 ++++ b/tools/objtool/builtin.h
9415 +@@ -17,6 +17,12 @@
9416 + #ifndef _BUILTIN_H
9417 + #define _BUILTIN_H
9418 +
9419 ++#include <subcmd/parse-options.h>
9420 ++
9421 ++extern const struct option check_options[];
9422 ++extern bool no_fp, no_unreachable, retpoline, module;
9423 ++
9424 + extern int cmd_check(int argc, const char **argv);
9425 ++extern int cmd_orc(int argc, const char **argv);
9426 +
9427 + #endif /* _BUILTIN_H */
9428 +diff --git a/tools/objtool/cfi.h b/tools/objtool/cfi.h
9429 +new file mode 100644
9430 +index 000000000000..2fe883c665c7
9431 +--- /dev/null
9432 ++++ b/tools/objtool/cfi.h
9433 +@@ -0,0 +1,55 @@
9434 ++/*
9435 ++ * Copyright (C) 2015-2017 Josh Poimboeuf <jpoimboe@××××××.com>
9436 ++ *
9437 ++ * This program is free software; you can redistribute it and/or
9438 ++ * modify it under the terms of the GNU General Public License
9439 ++ * as published by the Free Software Foundation; either version 2
9440 ++ * of the License, or (at your option) any later version.
9441 ++ *
9442 ++ * This program is distributed in the hope that it will be useful,
9443 ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
9444 ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9445 ++ * GNU General Public License for more details.
9446 ++ *
9447 ++ * You should have received a copy of the GNU General Public License
9448 ++ * along with this program; if not, see <http://www.gnu.org/licenses/>.
9449 ++ */
9450 ++
9451 ++#ifndef _OBJTOOL_CFI_H
9452 ++#define _OBJTOOL_CFI_H
9453 ++
9454 ++#define CFI_UNDEFINED -1
9455 ++#define CFI_CFA -2
9456 ++#define CFI_SP_INDIRECT -3
9457 ++#define CFI_BP_INDIRECT -4
9458 ++
9459 ++#define CFI_AX 0
9460 ++#define CFI_DX 1
9461 ++#define CFI_CX 2
9462 ++#define CFI_BX 3
9463 ++#define CFI_SI 4
9464 ++#define CFI_DI 5
9465 ++#define CFI_BP 6
9466 ++#define CFI_SP 7
9467 ++#define CFI_R8 8
9468 ++#define CFI_R9 9
9469 ++#define CFI_R10 10
9470 ++#define CFI_R11 11
9471 ++#define CFI_R12 12
9472 ++#define CFI_R13 13
9473 ++#define CFI_R14 14
9474 ++#define CFI_R15 15
9475 ++#define CFI_RA 16
9476 ++#define CFI_NUM_REGS 17
9477 ++
9478 ++struct cfi_reg {
9479 ++ int base;
9480 ++ int offset;
9481 ++};
9482 ++
9483 ++struct cfi_state {
9484 ++ struct cfi_reg cfa;
9485 ++ struct cfi_reg regs[CFI_NUM_REGS];
9486 ++};
9487 ++
9488 ++#endif /* _OBJTOOL_CFI_H */
9489 +diff --git a/tools/objtool/check.c b/tools/objtool/check.c
9490 +new file mode 100644
9491 +index 000000000000..e128d1c71c30
9492 +--- /dev/null
9493 ++++ b/tools/objtool/check.c
9494 +@@ -0,0 +1,2209 @@
9495 ++/*
9496 ++ * Copyright (C) 2015-2017 Josh Poimboeuf <jpoimboe@××××××.com>
9497 ++ *
9498 ++ * This program is free software; you can redistribute it and/or
9499 ++ * modify it under the terms of the GNU General Public License
9500 ++ * as published by the Free Software Foundation; either version 2
9501 ++ * of the License, or (at your option) any later version.
9502 ++ *
9503 ++ * This program is distributed in the hope that it will be useful,
9504 ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
9505 ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9506 ++ * GNU General Public License for more details.
9507 ++ *
9508 ++ * You should have received a copy of the GNU General Public License
9509 ++ * along with this program; if not, see <http://www.gnu.org/licenses/>.
9510 ++ */
9511 ++
9512 ++#include <string.h>
9513 ++#include <stdlib.h>
9514 ++
9515 ++#include "builtin.h"
9516 ++#include "check.h"
9517 ++#include "elf.h"
9518 ++#include "special.h"
9519 ++#include "arch.h"
9520 ++#include "warn.h"
9521 ++
9522 ++#include <linux/hashtable.h>
9523 ++#include <linux/kernel.h>
9524 ++
9525 ++struct alternative {
9526 ++ struct list_head list;
9527 ++ struct instruction *insn;
9528 ++};
9529 ++
9530 ++const char *objname;
9531 ++struct cfi_state initial_func_cfi;
9532 ++
9533 ++struct instruction *find_insn(struct objtool_file *file,
9534 ++ struct section *sec, unsigned long offset)
9535 ++{
9536 ++ struct instruction *insn;
9537 ++
9538 ++ hash_for_each_possible(file->insn_hash, insn, hash, offset)
9539 ++ if (insn->sec == sec && insn->offset == offset)
9540 ++ return insn;
9541 ++
9542 ++ return NULL;
9543 ++}
9544 ++
9545 ++static struct instruction *next_insn_same_sec(struct objtool_file *file,
9546 ++ struct instruction *insn)
9547 ++{
9548 ++ struct instruction *next = list_next_entry(insn, list);
9549 ++
9550 ++ if (!next || &next->list == &file->insn_list || next->sec != insn->sec)
9551 ++ return NULL;
9552 ++
9553 ++ return next;
9554 ++}
9555 ++
9556 ++static struct instruction *next_insn_same_func(struct objtool_file *file,
9557 ++ struct instruction *insn)
9558 ++{
9559 ++ struct instruction *next = list_next_entry(insn, list);
9560 ++ struct symbol *func = insn->func;
9561 ++
9562 ++ if (!func)
9563 ++ return NULL;
9564 ++
9565 ++ if (&next->list != &file->insn_list && next->func == func)
9566 ++ return next;
9567 ++
9568 ++ /* Check if we're already in the subfunction: */
9569 ++ if (func == func->cfunc)
9570 ++ return NULL;
9571 ++
9572 ++ /* Move to the subfunction: */
9573 ++ return find_insn(file, func->cfunc->sec, func->cfunc->offset);
9574 ++}
9575 ++
9576 ++#define func_for_each_insn_all(file, func, insn) \
9577 ++ for (insn = find_insn(file, func->sec, func->offset); \
9578 ++ insn; \
9579 ++ insn = next_insn_same_func(file, insn))
9580 ++
9581 ++#define func_for_each_insn(file, func, insn) \
9582 ++ for (insn = find_insn(file, func->sec, func->offset); \
9583 ++ insn && &insn->list != &file->insn_list && \
9584 ++ insn->sec == func->sec && \
9585 ++ insn->offset < func->offset + func->len; \
9586 ++ insn = list_next_entry(insn, list))
9587 ++
9588 ++#define func_for_each_insn_continue_reverse(file, func, insn) \
9589 ++ for (insn = list_prev_entry(insn, list); \
9590 ++ &insn->list != &file->insn_list && \
9591 ++ insn->sec == func->sec && insn->offset >= func->offset; \
9592 ++ insn = list_prev_entry(insn, list))
9593 ++
9594 ++#define sec_for_each_insn_from(file, insn) \
9595 ++ for (; insn; insn = next_insn_same_sec(file, insn))
9596 ++
9597 ++#define sec_for_each_insn_continue(file, insn) \
9598 ++ for (insn = next_insn_same_sec(file, insn); insn; \
9599 ++ insn = next_insn_same_sec(file, insn))
9600 ++
9601 ++/*
9602 ++ * Check if the function has been manually whitelisted with the
9603 ++ * STACK_FRAME_NON_STANDARD macro, or if it should be automatically whitelisted
9604 ++ * due to its use of a context switching instruction.
9605 ++ */
9606 ++static bool ignore_func(struct objtool_file *file, struct symbol *func)
9607 ++{
9608 ++ struct rela *rela;
9609 ++
9610 ++ /* check for STACK_FRAME_NON_STANDARD */
9611 ++ if (file->whitelist && file->whitelist->rela)
9612 ++ list_for_each_entry(rela, &file->whitelist->rela->rela_list, list) {
9613 ++ if (rela->sym->type == STT_SECTION &&
9614 ++ rela->sym->sec == func->sec &&
9615 ++ rela->addend == func->offset)
9616 ++ return true;
9617 ++ if (rela->sym->type == STT_FUNC && rela->sym == func)
9618 ++ return true;
9619 ++ }
9620 ++
9621 ++ return false;
9622 ++}
9623 ++
9624 ++/*
9625 ++ * This checks to see if the given function is a "noreturn" function.
9626 ++ *
9627 ++ * For global functions which are outside the scope of this object file, we
9628 ++ * have to keep a manual list of them.
9629 ++ *
9630 ++ * For local functions, we have to detect them manually by simply looking for
9631 ++ * the lack of a return instruction.
9632 ++ *
9633 ++ * Returns:
9634 ++ * -1: error
9635 ++ * 0: no dead end
9636 ++ * 1: dead end
9637 ++ */
9638 ++static int __dead_end_function(struct objtool_file *file, struct symbol *func,
9639 ++ int recursion)
9640 ++{
9641 ++ int i;
9642 ++ struct instruction *insn;
9643 ++ bool empty = true;
9644 ++
9645 ++ /*
9646 ++ * Unfortunately these have to be hard coded because the noreturn
9647 ++ * attribute isn't provided in ELF data.
9648 ++ */
9649 ++ static const char * const global_noreturns[] = {
9650 ++ "__stack_chk_fail",
9651 ++ "panic",
9652 ++ "do_exit",
9653 ++ "do_task_dead",
9654 ++ "__module_put_and_exit",
9655 ++ "complete_and_exit",
9656 ++ "kvm_spurious_fault",
9657 ++ "__reiserfs_panic",
9658 ++ "lbug_with_loc",
9659 ++ "fortify_panic",
9660 ++ };
9661 ++
9662 ++ if (func->bind == STB_WEAK)
9663 ++ return 0;
9664 ++
9665 ++ if (func->bind == STB_GLOBAL)
9666 ++ for (i = 0; i < ARRAY_SIZE(global_noreturns); i++)
9667 ++ if (!strcmp(func->name, global_noreturns[i]))
9668 ++ return 1;
9669 ++
9670 ++ if (!func->len)
9671 ++ return 0;
9672 ++
9673 ++ insn = find_insn(file, func->sec, func->offset);
9674 ++ if (!insn->func)
9675 ++ return 0;
9676 ++
9677 ++ func_for_each_insn_all(file, func, insn) {
9678 ++ empty = false;
9679 ++
9680 ++ if (insn->type == INSN_RETURN)
9681 ++ return 0;
9682 ++ }
9683 ++
9684 ++ if (empty)
9685 ++ return 0;
9686 ++
9687 ++ /*
9688 ++ * A function can have a sibling call instead of a return. In that
9689 ++ * case, the function's dead-end status depends on whether the target
9690 ++ * of the sibling call returns.
9691 ++ */
9692 ++ func_for_each_insn_all(file, func, insn) {
9693 ++ if (insn->type == INSN_JUMP_UNCONDITIONAL) {
9694 ++ struct instruction *dest = insn->jump_dest;
9695 ++
9696 ++ if (!dest)
9697 ++ /* sibling call to another file */
9698 ++ return 0;
9699 ++
9700 ++ if (dest->func && dest->func->pfunc != insn->func->pfunc) {
9701 ++
9702 ++ /* local sibling call */
9703 ++ if (recursion == 5) {
9704 ++ /*
9705 ++ * Infinite recursion: two functions
9706 ++ * have sibling calls to each other.
9707 ++ * This is a very rare case. It means
9708 ++ * they aren't dead ends.
9709 ++ */
9710 ++ return 0;
9711 ++ }
9712 ++
9713 ++ return __dead_end_function(file, dest->func,
9714 ++ recursion + 1);
9715 ++ }
9716 ++ }
9717 ++
9718 ++ if (insn->type == INSN_JUMP_DYNAMIC && list_empty(&insn->alts))
9719 ++ /* sibling call */
9720 ++ return 0;
9721 ++ }
9722 ++
9723 ++ return 1;
9724 ++}
9725 ++
9726 ++static int dead_end_function(struct objtool_file *file, struct symbol *func)
9727 ++{
9728 ++ return __dead_end_function(file, func, 0);
9729 ++}
9730 ++
9731 ++static void clear_insn_state(struct insn_state *state)
9732 ++{
9733 ++ int i;
9734 ++
9735 ++ memset(state, 0, sizeof(*state));
9736 ++ state->cfa.base = CFI_UNDEFINED;
9737 ++ for (i = 0; i < CFI_NUM_REGS; i++) {
9738 ++ state->regs[i].base = CFI_UNDEFINED;
9739 ++ state->vals[i].base = CFI_UNDEFINED;
9740 ++ }
9741 ++ state->drap_reg = CFI_UNDEFINED;
9742 ++ state->drap_offset = -1;
9743 ++}
9744 ++
9745 ++/*
9746 ++ * Call the arch-specific instruction decoder for all the instructions and add
9747 ++ * them to the global instruction list.
9748 ++ */
9749 ++static int decode_instructions(struct objtool_file *file)
9750 ++{
9751 ++ struct section *sec;
9752 ++ struct symbol *func;
9753 ++ unsigned long offset;
9754 ++ struct instruction *insn;
9755 ++ int ret;
9756 ++
9757 ++ for_each_sec(file, sec) {
9758 ++
9759 ++ if (!(sec->sh.sh_flags & SHF_EXECINSTR))
9760 ++ continue;
9761 ++
9762 ++ if (strcmp(sec->name, ".altinstr_replacement") &&
9763 ++ strcmp(sec->name, ".altinstr_aux") &&
9764 ++ strncmp(sec->name, ".discard.", 9))
9765 ++ sec->text = true;
9766 ++
9767 ++ for (offset = 0; offset < sec->len; offset += insn->len) {
9768 ++ insn = malloc(sizeof(*insn));
9769 ++ if (!insn) {
9770 ++ WARN("malloc failed");
9771 ++ return -1;
9772 ++ }
9773 ++ memset(insn, 0, sizeof(*insn));
9774 ++ INIT_LIST_HEAD(&insn->alts);
9775 ++ clear_insn_state(&insn->state);
9776 ++
9777 ++ insn->sec = sec;
9778 ++ insn->offset = offset;
9779 ++
9780 ++ ret = arch_decode_instruction(file->elf, sec, offset,
9781 ++ sec->len - offset,
9782 ++ &insn->len, &insn->type,
9783 ++ &insn->immediate,
9784 ++ &insn->stack_op);
9785 ++ if (ret)
9786 ++ goto err;
9787 ++
9788 ++ if (!insn->type || insn->type > INSN_LAST) {
9789 ++ WARN_FUNC("invalid instruction type %d",
9790 ++ insn->sec, insn->offset, insn->type);
9791 ++ ret = -1;
9792 ++ goto err;
9793 ++ }
9794 ++
9795 ++ hash_add(file->insn_hash, &insn->hash, insn->offset);
9796 ++ list_add_tail(&insn->list, &file->insn_list);
9797 ++ }
9798 ++
9799 ++ list_for_each_entry(func, &sec->symbol_list, list) {
9800 ++ if (func->type != STT_FUNC)
9801 ++ continue;
9802 ++
9803 ++ if (!find_insn(file, sec, func->offset)) {
9804 ++ WARN("%s(): can't find starting instruction",
9805 ++ func->name);
9806 ++ return -1;
9807 ++ }
9808 ++
9809 ++ func_for_each_insn(file, func, insn)
9810 ++ if (!insn->func)
9811 ++ insn->func = func;
9812 ++ }
9813 ++ }
9814 ++
9815 ++ return 0;
9816 ++
9817 ++err:
9818 ++ free(insn);
9819 ++ return ret;
9820 ++}
9821 ++
9822 ++/*
9823 ++ * Mark "ud2" instructions and manually annotated dead ends.
9824 ++ */
9825 ++static int add_dead_ends(struct objtool_file *file)
9826 ++{
9827 ++ struct section *sec;
9828 ++ struct rela *rela;
9829 ++ struct instruction *insn;
9830 ++ bool found;
9831 ++
9832 ++ /*
9833 ++ * By default, "ud2" is a dead end unless otherwise annotated, because
9834 ++ * GCC 7 inserts it for certain divide-by-zero cases.
9835 ++ */
9836 ++ for_each_insn(file, insn)
9837 ++ if (insn->type == INSN_BUG)
9838 ++ insn->dead_end = true;
9839 ++
9840 ++ /*
9841 ++ * Check for manually annotated dead ends.
9842 ++ */
9843 ++ sec = find_section_by_name(file->elf, ".rela.discard.unreachable");
9844 ++ if (!sec)
9845 ++ goto reachable;
9846 ++
9847 ++ list_for_each_entry(rela, &sec->rela_list, list) {
9848 ++ if (rela->sym->type != STT_SECTION) {
9849 ++ WARN("unexpected relocation symbol type in %s", sec->name);
9850 ++ return -1;
9851 ++ }
9852 ++ insn = find_insn(file, rela->sym->sec, rela->addend);
9853 ++ if (insn)
9854 ++ insn = list_prev_entry(insn, list);
9855 ++ else if (rela->addend == rela->sym->sec->len) {
9856 ++ found = false;
9857 ++ list_for_each_entry_reverse(insn, &file->insn_list, list) {
9858 ++ if (insn->sec == rela->sym->sec) {
9859 ++ found = true;
9860 ++ break;
9861 ++ }
9862 ++ }
9863 ++
9864 ++ if (!found) {
9865 ++ WARN("can't find unreachable insn at %s+0x%x",
9866 ++ rela->sym->sec->name, rela->addend);
9867 ++ return -1;
9868 ++ }
9869 ++ } else {
9870 ++ WARN("can't find unreachable insn at %s+0x%x",
9871 ++ rela->sym->sec->name, rela->addend);
9872 ++ return -1;
9873 ++ }
9874 ++
9875 ++ insn->dead_end = true;
9876 ++ }
9877 ++
9878 ++reachable:
9879 ++ /*
9880 ++ * These manually annotated reachable checks are needed for GCC 4.4,
9881 ++ * where the Linux unreachable() macro isn't supported. In that case
9882 ++ * GCC doesn't know the "ud2" is fatal, so it generates code as if it's
9883 ++ * not a dead end.
9884 ++ */
9885 ++ sec = find_section_by_name(file->elf, ".rela.discard.reachable");
9886 ++ if (!sec)
9887 ++ return 0;
9888 ++
9889 ++ list_for_each_entry(rela, &sec->rela_list, list) {
9890 ++ if (rela->sym->type != STT_SECTION) {
9891 ++ WARN("unexpected relocation symbol type in %s", sec->name);
9892 ++ return -1;
9893 ++ }
9894 ++ insn = find_insn(file, rela->sym->sec, rela->addend);
9895 ++ if (insn)
9896 ++ insn = list_prev_entry(insn, list);
9897 ++ else if (rela->addend == rela->sym->sec->len) {
9898 ++ found = false;
9899 ++ list_for_each_entry_reverse(insn, &file->insn_list, list) {
9900 ++ if (insn->sec == rela->sym->sec) {
9901 ++ found = true;
9902 ++ break;
9903 ++ }
9904 ++ }
9905 ++
9906 ++ if (!found) {
9907 ++ WARN("can't find reachable insn at %s+0x%x",
9908 ++ rela->sym->sec->name, rela->addend);
9909 ++ return -1;
9910 ++ }
9911 ++ } else {
9912 ++ WARN("can't find reachable insn at %s+0x%x",
9913 ++ rela->sym->sec->name, rela->addend);
9914 ++ return -1;
9915 ++ }
9916 ++
9917 ++ insn->dead_end = false;
9918 ++ }
9919 ++
9920 ++ return 0;
9921 ++}
9922 ++
9923 ++/*
9924 ++ * Warnings shouldn't be reported for ignored functions.
9925 ++ */
9926 ++static void add_ignores(struct objtool_file *file)
9927 ++{
9928 ++ struct instruction *insn;
9929 ++ struct section *sec;
9930 ++ struct symbol *func;
9931 ++
9932 ++ for_each_sec(file, sec) {
9933 ++ list_for_each_entry(func, &sec->symbol_list, list) {
9934 ++ if (func->type != STT_FUNC)
9935 ++ continue;
9936 ++
9937 ++ if (!ignore_func(file, func))
9938 ++ continue;
9939 ++
9940 ++ func_for_each_insn_all(file, func, insn)
9941 ++ insn->ignore = true;
9942 ++ }
9943 ++ }
9944 ++}
9945 ++
9946 ++/*
9947 ++ * FIXME: For now, just ignore any alternatives which add retpolines. This is
9948 ++ * a temporary hack, as it doesn't allow ORC to unwind from inside a retpoline.
9949 ++ * But it at least allows objtool to understand the control flow *around* the
9950 ++ * retpoline.
9951 ++ */
9952 ++static int add_nospec_ignores(struct objtool_file *file)
9953 ++{
9954 ++ struct section *sec;
9955 ++ struct rela *rela;
9956 ++ struct instruction *insn;
9957 ++
9958 ++ sec = find_section_by_name(file->elf, ".rela.discard.nospec");
9959 ++ if (!sec)
9960 ++ return 0;
9961 ++
9962 ++ list_for_each_entry(rela, &sec->rela_list, list) {
9963 ++ if (rela->sym->type != STT_SECTION) {
9964 ++ WARN("unexpected relocation symbol type in %s", sec->name);
9965 ++ return -1;
9966 ++ }
9967 ++
9968 ++ insn = find_insn(file, rela->sym->sec, rela->addend);
9969 ++ if (!insn) {
9970 ++ WARN("bad .discard.nospec entry");
9971 ++ return -1;
9972 ++ }
9973 ++
9974 ++ insn->ignore_alts = true;
9975 ++ }
9976 ++
9977 ++ return 0;
9978 ++}
9979 ++
9980 ++/*
9981 ++ * Find the destination instructions for all jumps.
9982 ++ */
9983 ++static int add_jump_destinations(struct objtool_file *file)
9984 ++{
9985 ++ struct instruction *insn;
9986 ++ struct rela *rela;
9987 ++ struct section *dest_sec;
9988 ++ unsigned long dest_off;
9989 ++
9990 ++ for_each_insn(file, insn) {
9991 ++ if (insn->type != INSN_JUMP_CONDITIONAL &&
9992 ++ insn->type != INSN_JUMP_UNCONDITIONAL)
9993 ++ continue;
9994 ++
9995 ++ if (insn->ignore)
9996 ++ continue;
9997 ++
9998 ++ rela = find_rela_by_dest_range(insn->sec, insn->offset,
9999 ++ insn->len);
10000 ++ if (!rela) {
10001 ++ dest_sec = insn->sec;
10002 ++ dest_off = insn->offset + insn->len + insn->immediate;
10003 ++ } else if (rela->sym->type == STT_SECTION) {
10004 ++ dest_sec = rela->sym->sec;
10005 ++ dest_off = rela->addend + 4;
10006 ++ } else if (rela->sym->sec->idx) {
10007 ++ dest_sec = rela->sym->sec;
10008 ++ dest_off = rela->sym->sym.st_value + rela->addend + 4;
10009 ++ } else if (strstr(rela->sym->name, "_indirect_thunk_")) {
10010 ++ /*
10011 ++ * Retpoline jumps are really dynamic jumps in
10012 ++ * disguise, so convert them accordingly.
10013 ++ */
10014 ++ insn->type = INSN_JUMP_DYNAMIC;
10015 ++ insn->retpoline_safe = true;
10016 ++ continue;
10017 ++ } else {
10018 ++ /* sibling call */
10019 ++ insn->jump_dest = 0;
10020 ++ continue;
10021 ++ }
10022 ++
10023 ++ insn->jump_dest = find_insn(file, dest_sec, dest_off);
10024 ++ if (!insn->jump_dest) {
10025 ++
10026 ++ /*
10027 ++ * This is a special case where an alt instruction
10028 ++ * jumps past the end of the section. These are
10029 ++ * handled later in handle_group_alt().
10030 ++ */
10031 ++ if (!strcmp(insn->sec->name, ".altinstr_replacement"))
10032 ++ continue;
10033 ++
10034 ++ WARN_FUNC("can't find jump dest instruction at %s+0x%lx",
10035 ++ insn->sec, insn->offset, dest_sec->name,
10036 ++ dest_off);
10037 ++ return -1;
10038 ++ }
10039 ++ }
10040 ++
10041 ++ return 0;
10042 ++}
10043 ++
10044 ++/*
10045 ++ * Find the destination instructions for all calls.
10046 ++ */
10047 ++static int add_call_destinations(struct objtool_file *file)
10048 ++{
10049 ++ struct instruction *insn;
10050 ++ unsigned long dest_off;
10051 ++ struct rela *rela;
10052 ++
10053 ++ for_each_insn(file, insn) {
10054 ++ if (insn->type != INSN_CALL)
10055 ++ continue;
10056 ++
10057 ++ rela = find_rela_by_dest_range(insn->sec, insn->offset,
10058 ++ insn->len);
10059 ++ if (!rela) {
10060 ++ dest_off = insn->offset + insn->len + insn->immediate;
10061 ++ insn->call_dest = find_symbol_by_offset(insn->sec,
10062 ++ dest_off);
10063 ++
10064 ++ if (!insn->call_dest && !insn->ignore) {
10065 ++ WARN_FUNC("unsupported intra-function call",
10066 ++ insn->sec, insn->offset);
10067 ++ if (retpoline)
10068 ++ WARN("If this is a retpoline, please patch it in with alternatives and annotate it with ANNOTATE_NOSPEC_ALTERNATIVE.");
10069 ++ return -1;
10070 ++ }
10071 ++
10072 ++ } else if (rela->sym->type == STT_SECTION) {
10073 ++ insn->call_dest = find_symbol_by_offset(rela->sym->sec,
10074 ++ rela->addend+4);
10075 ++ if (!insn->call_dest ||
10076 ++ insn->call_dest->type != STT_FUNC) {
10077 ++ WARN_FUNC("can't find call dest symbol at %s+0x%x",
10078 ++ insn->sec, insn->offset,
10079 ++ rela->sym->sec->name,
10080 ++ rela->addend + 4);
10081 ++ return -1;
10082 ++ }
10083 ++ } else
10084 ++ insn->call_dest = rela->sym;
10085 ++ }
10086 ++
10087 ++ return 0;
10088 ++}
10089 ++
10090 ++/*
10091 ++ * The .alternatives section requires some extra special care, over and above
10092 ++ * what other special sections require:
10093 ++ *
10094 ++ * 1. Because alternatives are patched in-place, we need to insert a fake jump
10095 ++ * instruction at the end so that validate_branch() skips all the original
10096 ++ * replaced instructions when validating the new instruction path.
10097 ++ *
10098 ++ * 2. An added wrinkle is that the new instruction length might be zero. In
10099 ++ * that case the old instructions are replaced with noops. We simulate that
10100 ++ * by creating a fake jump as the only new instruction.
10101 ++ *
10102 ++ * 3. In some cases, the alternative section includes an instruction which
10103 ++ * conditionally jumps to the _end_ of the entry. We have to modify these
10104 ++ * jumps' destinations to point back to .text rather than the end of the
10105 ++ * entry in .altinstr_replacement.
10106 ++ *
10107 ++ * 4. It has been requested that we don't validate the !POPCNT feature path
10108 ++ * which is a "very very small percentage of machines".
10109 ++ */
10110 ++static int handle_group_alt(struct objtool_file *file,
10111 ++ struct special_alt *special_alt,
10112 ++ struct instruction *orig_insn,
10113 ++ struct instruction **new_insn)
10114 ++{
10115 ++ struct instruction *last_orig_insn, *last_new_insn, *insn, *fake_jump = NULL;
10116 ++ unsigned long dest_off;
10117 ++
10118 ++ last_orig_insn = NULL;
10119 ++ insn = orig_insn;
10120 ++ sec_for_each_insn_from(file, insn) {
10121 ++ if (insn->offset >= special_alt->orig_off + special_alt->orig_len)
10122 ++ break;
10123 ++
10124 ++ if (special_alt->skip_orig)
10125 ++ insn->type = INSN_NOP;
10126 ++
10127 ++ insn->alt_group = true;
10128 ++ last_orig_insn = insn;
10129 ++ }
10130 ++
10131 ++ if (next_insn_same_sec(file, last_orig_insn)) {
10132 ++ fake_jump = malloc(sizeof(*fake_jump));
10133 ++ if (!fake_jump) {
10134 ++ WARN("malloc failed");
10135 ++ return -1;
10136 ++ }
10137 ++ memset(fake_jump, 0, sizeof(*fake_jump));
10138 ++ INIT_LIST_HEAD(&fake_jump->alts);
10139 ++ clear_insn_state(&fake_jump->state);
10140 ++
10141 ++ fake_jump->sec = special_alt->new_sec;
10142 ++ fake_jump->offset = -1;
10143 ++ fake_jump->type = INSN_JUMP_UNCONDITIONAL;
10144 ++ fake_jump->jump_dest = list_next_entry(last_orig_insn, list);
10145 ++ fake_jump->ignore = true;
10146 ++ }
10147 ++
10148 ++ if (!special_alt->new_len) {
10149 ++ if (!fake_jump) {
10150 ++ WARN("%s: empty alternative at end of section",
10151 ++ special_alt->orig_sec->name);
10152 ++ return -1;
10153 ++ }
10154 ++
10155 ++ *new_insn = fake_jump;
10156 ++ return 0;
10157 ++ }
10158 ++
10159 ++ last_new_insn = NULL;
10160 ++ insn = *new_insn;
10161 ++ sec_for_each_insn_from(file, insn) {
10162 ++ if (insn->offset >= special_alt->new_off + special_alt->new_len)
10163 ++ break;
10164 ++
10165 ++ last_new_insn = insn;
10166 ++
10167 ++ insn->ignore = orig_insn->ignore_alts;
10168 ++
10169 ++ if (insn->type != INSN_JUMP_CONDITIONAL &&
10170 ++ insn->type != INSN_JUMP_UNCONDITIONAL)
10171 ++ continue;
10172 ++
10173 ++ if (!insn->immediate)
10174 ++ continue;
10175 ++
10176 ++ dest_off = insn->offset + insn->len + insn->immediate;
10177 ++ if (dest_off == special_alt->new_off + special_alt->new_len) {
10178 ++ if (!fake_jump) {
10179 ++ WARN("%s: alternative jump to end of section",
10180 ++ special_alt->orig_sec->name);
10181 ++ return -1;
10182 ++ }
10183 ++ insn->jump_dest = fake_jump;
10184 ++ }
10185 ++
10186 ++ if (!insn->jump_dest) {
10187 ++ WARN_FUNC("can't find alternative jump destination",
10188 ++ insn->sec, insn->offset);
10189 ++ return -1;
10190 ++ }
10191 ++ }
10192 ++
10193 ++ if (!last_new_insn) {
10194 ++ WARN_FUNC("can't find last new alternative instruction",
10195 ++ special_alt->new_sec, special_alt->new_off);
10196 ++ return -1;
10197 ++ }
10198 ++
10199 ++ if (fake_jump)
10200 ++ list_add(&fake_jump->list, &last_new_insn->list);
10201 ++
10202 ++ return 0;
10203 ++}
10204 ++
10205 ++/*
10206 ++ * A jump table entry can either convert a nop to a jump or a jump to a nop.
10207 ++ * If the original instruction is a jump, make the alt entry an effective nop
10208 ++ * by just skipping the original instruction.
10209 ++ */
10210 ++static int handle_jump_alt(struct objtool_file *file,
10211 ++ struct special_alt *special_alt,
10212 ++ struct instruction *orig_insn,
10213 ++ struct instruction **new_insn)
10214 ++{
10215 ++ if (orig_insn->type == INSN_NOP)
10216 ++ return 0;
10217 ++
10218 ++ if (orig_insn->type != INSN_JUMP_UNCONDITIONAL) {
10219 ++ WARN_FUNC("unsupported instruction at jump label",
10220 ++ orig_insn->sec, orig_insn->offset);
10221 ++ return -1;
10222 ++ }
10223 ++
10224 ++ *new_insn = list_next_entry(orig_insn, list);
10225 ++ return 0;
10226 ++}
10227 ++
10228 ++/*
10229 ++ * Read all the special sections which have alternate instructions which can be
10230 ++ * patched in or redirected to at runtime. Each instruction having alternate
10231 ++ * instruction(s) has them added to its insn->alts list, which will be
10232 ++ * traversed in validate_branch().
10233 ++ */
10234 ++static int add_special_section_alts(struct objtool_file *file)
10235 ++{
10236 ++ struct list_head special_alts;
10237 ++ struct instruction *orig_insn, *new_insn;
10238 ++ struct special_alt *special_alt, *tmp;
10239 ++ struct alternative *alt;
10240 ++ int ret;
10241 ++
10242 ++ ret = special_get_alts(file->elf, &special_alts);
10243 ++ if (ret)
10244 ++ return ret;
10245 ++
10246 ++ list_for_each_entry_safe(special_alt, tmp, &special_alts, list) {
10247 ++
10248 ++ orig_insn = find_insn(file, special_alt->orig_sec,
10249 ++ special_alt->orig_off);
10250 ++ if (!orig_insn) {
10251 ++ WARN_FUNC("special: can't find orig instruction",
10252 ++ special_alt->orig_sec, special_alt->orig_off);
10253 ++ ret = -1;
10254 ++ goto out;
10255 ++ }
10256 ++
10257 ++ new_insn = NULL;
10258 ++ if (!special_alt->group || special_alt->new_len) {
10259 ++ new_insn = find_insn(file, special_alt->new_sec,
10260 ++ special_alt->new_off);
10261 ++ if (!new_insn) {
10262 ++ WARN_FUNC("special: can't find new instruction",
10263 ++ special_alt->new_sec,
10264 ++ special_alt->new_off);
10265 ++ ret = -1;
10266 ++ goto out;
10267 ++ }
10268 ++ }
10269 ++
10270 ++ if (special_alt->group) {
10271 ++ ret = handle_group_alt(file, special_alt, orig_insn,
10272 ++ &new_insn);
10273 ++ if (ret)
10274 ++ goto out;
10275 ++ } else if (special_alt->jump_or_nop) {
10276 ++ ret = handle_jump_alt(file, special_alt, orig_insn,
10277 ++ &new_insn);
10278 ++ if (ret)
10279 ++ goto out;
10280 ++ }
10281 ++
10282 ++ alt = malloc(sizeof(*alt));
10283 ++ if (!alt) {
10284 ++ WARN("malloc failed");
10285 ++ ret = -1;
10286 ++ goto out;
10287 ++ }
10288 ++
10289 ++ alt->insn = new_insn;
10290 ++ list_add_tail(&alt->list, &orig_insn->alts);
10291 ++
10292 ++ list_del(&special_alt->list);
10293 ++ free(special_alt);
10294 ++ }
10295 ++
10296 ++out:
10297 ++ return ret;
10298 ++}
10299 ++
10300 ++static int add_switch_table(struct objtool_file *file, struct instruction *insn,
10301 ++ struct rela *table, struct rela *next_table)
10302 ++{
10303 ++ struct rela *rela = table;
10304 ++ struct instruction *alt_insn;
10305 ++ struct alternative *alt;
10306 ++ struct symbol *pfunc = insn->func->pfunc;
10307 ++ unsigned int prev_offset = 0;
10308 ++
10309 ++ list_for_each_entry_from(rela, &file->rodata->rela->rela_list, list) {
10310 ++ if (rela == next_table)
10311 ++ break;
10312 ++
10313 ++ /* Make sure the switch table entries are consecutive: */
10314 ++ if (prev_offset && rela->offset != prev_offset + 8)
10315 ++ break;
10316 ++
10317 ++ /* Detect function pointers from contiguous objects: */
10318 ++ if (rela->sym->sec == pfunc->sec &&
10319 ++ rela->addend == pfunc->offset)
10320 ++ break;
10321 ++
10322 ++ alt_insn = find_insn(file, rela->sym->sec, rela->addend);
10323 ++ if (!alt_insn)
10324 ++ break;
10325 ++
10326 ++ /* Make sure the jmp dest is in the function or subfunction: */
10327 ++ if (alt_insn->func->pfunc != pfunc)
10328 ++ break;
10329 ++
10330 ++ alt = malloc(sizeof(*alt));
10331 ++ if (!alt) {
10332 ++ WARN("malloc failed");
10333 ++ return -1;
10334 ++ }
10335 ++
10336 ++ alt->insn = alt_insn;
10337 ++ list_add_tail(&alt->list, &insn->alts);
10338 ++ prev_offset = rela->offset;
10339 ++ }
10340 ++
10341 ++ if (!prev_offset) {
10342 ++ WARN_FUNC("can't find switch jump table",
10343 ++ insn->sec, insn->offset);
10344 ++ return -1;
10345 ++ }
10346 ++
10347 ++ return 0;
10348 ++}
10349 ++
10350 ++/*
10351 ++ * find_switch_table() - Given a dynamic jump, find the switch jump table in
10352 ++ * .rodata associated with it.
10353 ++ *
10354 ++ * There are 3 basic patterns:
10355 ++ *
10356 ++ * 1. jmpq *[rodata addr](,%reg,8)
10357 ++ *
10358 ++ * This is the most common case by far. It jumps to an address in a simple
10359 ++ * jump table which is stored in .rodata.
10360 ++ *
10361 ++ * 2. jmpq *[rodata addr](%rip)
10362 ++ *
10363 ++ * This is caused by a rare GCC quirk, currently only seen in three driver
10364 ++ * functions in the kernel, only with certain obscure non-distro configs.
10365 ++ *
10366 ++ * As part of an optimization, GCC makes a copy of an existing switch jump
10367 ++ * table, modifies it, and then hard-codes the jump (albeit with an indirect
10368 ++ * jump) to use a single entry in the table. The rest of the jump table and
10369 ++ * some of its jump targets remain as dead code.
10370 ++ *
10371 ++ * In such a case we can just crudely ignore all unreachable instruction
10372 ++ * warnings for the entire object file. Ideally we would just ignore them
10373 ++ * for the function, but that would require redesigning the code quite a
10374 ++ * bit. And honestly that's just not worth doing: unreachable instruction
10375 ++ * warnings are of questionable value anyway, and this is such a rare issue.
10376 ++ *
10377 ++ * 3. mov [rodata addr],%reg1
10378 ++ * ... some instructions ...
10379 ++ * jmpq *(%reg1,%reg2,8)
10380 ++ *
10381 ++ * This is a fairly uncommon pattern which is new for GCC 6. As of this
10382 ++ * writing, there are 11 occurrences of it in the allmodconfig kernel.
10383 ++ *
10384 ++ * As of GCC 7 there are quite a few more of these and the 'in between' code
10385 ++ * is significant. Esp. with KASAN enabled some of the code between the mov
10386 ++ * and jmpq uses .rodata itself, which can confuse things.
10387 ++ *
10388 ++ * TODO: Once we have DWARF CFI and smarter instruction decoding logic,
10389 ++ * ensure the same register is used in the mov and jump instructions.
10390 ++ *
10391 ++ * NOTE: RETPOLINE made it harder still to decode dynamic jumps.
10392 ++ */
10393 ++static struct rela *find_switch_table(struct objtool_file *file,
10394 ++ struct symbol *func,
10395 ++ struct instruction *insn)
10396 ++{
10397 ++ struct rela *text_rela, *rodata_rela;
10398 ++ struct instruction *orig_insn = insn;
10399 ++ unsigned long table_offset;
10400 ++
10401 ++ /*
10402 ++ * Backward search using the @first_jump_src links, these help avoid
10403 ++ * much of the 'in between' code. Which avoids us getting confused by
10404 ++ * it.
10405 ++ */
10406 ++ for (;
10407 ++ &insn->list != &file->insn_list &&
10408 ++ insn->sec == func->sec &&
10409 ++ insn->offset >= func->offset;
10410 ++
10411 ++ insn = insn->first_jump_src ?: list_prev_entry(insn, list)) {
10412 ++
10413 ++ if (insn != orig_insn && insn->type == INSN_JUMP_DYNAMIC)
10414 ++ break;
10415 ++
10416 ++ /* allow small jumps within the range */
10417 ++ if (insn->type == INSN_JUMP_UNCONDITIONAL &&
10418 ++ insn->jump_dest &&
10419 ++ (insn->jump_dest->offset <= insn->offset ||
10420 ++ insn->jump_dest->offset > orig_insn->offset))
10421 ++ break;
10422 ++
10423 ++ /* look for a relocation which references .rodata */
10424 ++ text_rela = find_rela_by_dest_range(insn->sec, insn->offset,
10425 ++ insn->len);
10426 ++ if (!text_rela || text_rela->sym != file->rodata->sym)
10427 ++ continue;
10428 ++
10429 ++ table_offset = text_rela->addend;
10430 ++ if (text_rela->type == R_X86_64_PC32)
10431 ++ table_offset += 4;
10432 ++
10433 ++ /*
10434 ++ * Make sure the .rodata address isn't associated with a
10435 ++ * symbol. gcc jump tables are anonymous data.
10436 ++ */
10437 ++ if (find_symbol_containing(file->rodata, table_offset))
10438 ++ continue;
10439 ++
10440 ++ rodata_rela = find_rela_by_dest(file->rodata, table_offset);
10441 ++ if (rodata_rela) {
10442 ++ /*
10443 ++ * Use of RIP-relative switch jumps is quite rare, and
10444 ++ * indicates a rare GCC quirk/bug which can leave dead
10445 ++ * code behind.
10446 ++ */
10447 ++ if (text_rela->type == R_X86_64_PC32)
10448 ++ file->ignore_unreachables = true;
10449 ++
10450 ++ return rodata_rela;
10451 ++ }
10452 ++ }
10453 ++
10454 ++ return NULL;
10455 ++}
10456 ++
10457 ++
10458 ++static int add_func_switch_tables(struct objtool_file *file,
10459 ++ struct symbol *func)
10460 ++{
10461 ++ struct instruction *insn, *last = NULL, *prev_jump = NULL;
10462 ++ struct rela *rela, *prev_rela = NULL;
10463 ++ int ret;
10464 ++
10465 ++ func_for_each_insn_all(file, func, insn) {
10466 ++ if (!last)
10467 ++ last = insn;
10468 ++
10469 ++ /*
10470 ++ * Store back-pointers for unconditional forward jumps such
10471 ++ * that find_switch_table() can back-track using those and
10472 ++ * avoid some potentially confusing code.
10473 ++ */
10474 ++ if (insn->type == INSN_JUMP_UNCONDITIONAL && insn->jump_dest &&
10475 ++ insn->offset > last->offset &&
10476 ++ insn->jump_dest->offset > insn->offset &&
10477 ++ !insn->jump_dest->first_jump_src) {
10478 ++
10479 ++ insn->jump_dest->first_jump_src = insn;
10480 ++ last = insn->jump_dest;
10481 ++ }
10482 ++
10483 ++ if (insn->type != INSN_JUMP_DYNAMIC)
10484 ++ continue;
10485 ++
10486 ++ rela = find_switch_table(file, func, insn);
10487 ++ if (!rela)
10488 ++ continue;
10489 ++
10490 ++ /*
10491 ++ * We found a switch table, but we don't know yet how big it
10492 ++ * is. Don't add it until we reach the end of the function or
10493 ++ * the beginning of another switch table in the same function.
10494 ++ */
10495 ++ if (prev_jump) {
10496 ++ ret = add_switch_table(file, prev_jump, prev_rela, rela);
10497 ++ if (ret)
10498 ++ return ret;
10499 ++ }
10500 ++
10501 ++ prev_jump = insn;
10502 ++ prev_rela = rela;
10503 ++ }
10504 ++
10505 ++ if (prev_jump) {
10506 ++ ret = add_switch_table(file, prev_jump, prev_rela, NULL);
10507 ++ if (ret)
10508 ++ return ret;
10509 ++ }
10510 ++
10511 ++ return 0;
10512 ++}
10513 ++
10514 ++/*
10515 ++ * For some switch statements, gcc generates a jump table in the .rodata
10516 ++ * section which contains a list of addresses within the function to jump to.
10517 ++ * This finds these jump tables and adds them to the insn->alts lists.
10518 ++ */
10519 ++static int add_switch_table_alts(struct objtool_file *file)
10520 ++{
10521 ++ struct section *sec;
10522 ++ struct symbol *func;
10523 ++ int ret;
10524 ++
10525 ++ if (!file->rodata || !file->rodata->rela)
10526 ++ return 0;
10527 ++
10528 ++ for_each_sec(file, sec) {
10529 ++ list_for_each_entry(func, &sec->symbol_list, list) {
10530 ++ if (func->type != STT_FUNC)
10531 ++ continue;
10532 ++
10533 ++ ret = add_func_switch_tables(file, func);
10534 ++ if (ret)
10535 ++ return ret;
10536 ++ }
10537 ++ }
10538 ++
10539 ++ return 0;
10540 ++}
10541 ++
10542 ++static int read_unwind_hints(struct objtool_file *file)
10543 ++{
10544 ++ struct section *sec, *relasec;
10545 ++ struct rela *rela;
10546 ++ struct unwind_hint *hint;
10547 ++ struct instruction *insn;
10548 ++ struct cfi_reg *cfa;
10549 ++ int i;
10550 ++
10551 ++ sec = find_section_by_name(file->elf, ".discard.unwind_hints");
10552 ++ if (!sec)
10553 ++ return 0;
10554 ++
10555 ++ relasec = sec->rela;
10556 ++ if (!relasec) {
10557 ++ WARN("missing .rela.discard.unwind_hints section");
10558 ++ return -1;
10559 ++ }
10560 ++
10561 ++ if (sec->len % sizeof(struct unwind_hint)) {
10562 ++ WARN("struct unwind_hint size mismatch");
10563 ++ return -1;
10564 ++ }
10565 ++
10566 ++ file->hints = true;
10567 ++
10568 ++ for (i = 0; i < sec->len / sizeof(struct unwind_hint); i++) {
10569 ++ hint = (struct unwind_hint *)sec->data->d_buf + i;
10570 ++
10571 ++ rela = find_rela_by_dest(sec, i * sizeof(*hint));
10572 ++ if (!rela) {
10573 ++ WARN("can't find rela for unwind_hints[%d]", i);
10574 ++ return -1;
10575 ++ }
10576 ++
10577 ++ insn = find_insn(file, rela->sym->sec, rela->addend);
10578 ++ if (!insn) {
10579 ++ WARN("can't find insn for unwind_hints[%d]", i);
10580 ++ return -1;
10581 ++ }
10582 ++
10583 ++ cfa = &insn->state.cfa;
10584 ++
10585 ++ if (hint->type == UNWIND_HINT_TYPE_SAVE) {
10586 ++ insn->save = true;
10587 ++ continue;
10588 ++
10589 ++ } else if (hint->type == UNWIND_HINT_TYPE_RESTORE) {
10590 ++ insn->restore = true;
10591 ++ insn->hint = true;
10592 ++ continue;
10593 ++ }
10594 ++
10595 ++ insn->hint = true;
10596 ++
10597 ++ switch (hint->sp_reg) {
10598 ++ case ORC_REG_UNDEFINED:
10599 ++ cfa->base = CFI_UNDEFINED;
10600 ++ break;
10601 ++ case ORC_REG_SP:
10602 ++ cfa->base = CFI_SP;
10603 ++ break;
10604 ++ case ORC_REG_BP:
10605 ++ cfa->base = CFI_BP;
10606 ++ break;
10607 ++ case ORC_REG_SP_INDIRECT:
10608 ++ cfa->base = CFI_SP_INDIRECT;
10609 ++ break;
10610 ++ case ORC_REG_R10:
10611 ++ cfa->base = CFI_R10;
10612 ++ break;
10613 ++ case ORC_REG_R13:
10614 ++ cfa->base = CFI_R13;
10615 ++ break;
10616 ++ case ORC_REG_DI:
10617 ++ cfa->base = CFI_DI;
10618 ++ break;
10619 ++ case ORC_REG_DX:
10620 ++ cfa->base = CFI_DX;
10621 ++ break;
10622 ++ default:
10623 ++ WARN_FUNC("unsupported unwind_hint sp base reg %d",
10624 ++ insn->sec, insn->offset, hint->sp_reg);
10625 ++ return -1;
10626 ++ }
10627 ++
10628 ++ cfa->offset = hint->sp_offset;
10629 ++ insn->state.type = hint->type;
10630 ++ }
10631 ++
10632 ++ return 0;
10633 ++}
10634 ++
10635 ++static int read_retpoline_hints(struct objtool_file *file)
10636 ++{
10637 ++ struct section *sec;
10638 ++ struct instruction *insn;
10639 ++ struct rela *rela;
10640 ++
10641 ++ sec = find_section_by_name(file->elf, ".rela.discard.retpoline_safe");
10642 ++ if (!sec)
10643 ++ return 0;
10644 ++
10645 ++ list_for_each_entry(rela, &sec->rela_list, list) {
10646 ++ if (rela->sym->type != STT_SECTION) {
10647 ++ WARN("unexpected relocation symbol type in %s", sec->name);
10648 ++ return -1;
10649 ++ }
10650 ++
10651 ++ insn = find_insn(file, rela->sym->sec, rela->addend);
10652 ++ if (!insn) {
10653 ++ WARN("bad .discard.retpoline_safe entry");
10654 ++ return -1;
10655 ++ }
10656 ++
10657 ++ if (insn->type != INSN_JUMP_DYNAMIC &&
10658 ++ insn->type != INSN_CALL_DYNAMIC) {
10659 ++ WARN_FUNC("retpoline_safe hint not an indirect jump/call",
10660 ++ insn->sec, insn->offset);
10661 ++ return -1;
10662 ++ }
10663 ++
10664 ++ insn->retpoline_safe = true;
10665 ++ }
10666 ++
10667 ++ return 0;
10668 ++}
10669 ++
10670 ++static int decode_sections(struct objtool_file *file)
10671 ++{
10672 ++ int ret;
10673 ++
10674 ++ ret = decode_instructions(file);
10675 ++ if (ret)
10676 ++ return ret;
10677 ++
10678 ++ ret = add_dead_ends(file);
10679 ++ if (ret)
10680 ++ return ret;
10681 ++
10682 ++ add_ignores(file);
10683 ++
10684 ++ ret = add_nospec_ignores(file);
10685 ++ if (ret)
10686 ++ return ret;
10687 ++
10688 ++ ret = add_jump_destinations(file);
10689 ++ if (ret)
10690 ++ return ret;
10691 ++
10692 ++ ret = add_special_section_alts(file);
10693 ++ if (ret)
10694 ++ return ret;
10695 ++
10696 ++ ret = add_call_destinations(file);
10697 ++ if (ret)
10698 ++ return ret;
10699 ++
10700 ++ ret = add_switch_table_alts(file);
10701 ++ if (ret)
10702 ++ return ret;
10703 ++
10704 ++ ret = read_unwind_hints(file);
10705 ++ if (ret)
10706 ++ return ret;
10707 ++
10708 ++ ret = read_retpoline_hints(file);
10709 ++ if (ret)
10710 ++ return ret;
10711 ++
10712 ++ return 0;
10713 ++}
10714 ++
10715 ++static bool is_fentry_call(struct instruction *insn)
10716 ++{
10717 ++ if (insn->type == INSN_CALL &&
10718 ++ insn->call_dest->type == STT_NOTYPE &&
10719 ++ !strcmp(insn->call_dest->name, "__fentry__"))
10720 ++ return true;
10721 ++
10722 ++ return false;
10723 ++}
10724 ++
10725 ++static bool has_modified_stack_frame(struct insn_state *state)
10726 ++{
10727 ++ int i;
10728 ++
10729 ++ if (state->cfa.base != initial_func_cfi.cfa.base ||
10730 ++ state->cfa.offset != initial_func_cfi.cfa.offset ||
10731 ++ state->stack_size != initial_func_cfi.cfa.offset ||
10732 ++ state->drap)
10733 ++ return true;
10734 ++
10735 ++ for (i = 0; i < CFI_NUM_REGS; i++)
10736 ++ if (state->regs[i].base != initial_func_cfi.regs[i].base ||
10737 ++ state->regs[i].offset != initial_func_cfi.regs[i].offset)
10738 ++ return true;
10739 ++
10740 ++ return false;
10741 ++}
10742 ++
10743 ++static bool has_valid_stack_frame(struct insn_state *state)
10744 ++{
10745 ++ if (state->cfa.base == CFI_BP && state->regs[CFI_BP].base == CFI_CFA &&
10746 ++ state->regs[CFI_BP].offset == -16)
10747 ++ return true;
10748 ++
10749 ++ if (state->drap && state->regs[CFI_BP].base == CFI_BP)
10750 ++ return true;
10751 ++
10752 ++ return false;
10753 ++}
10754 ++
10755 ++static int update_insn_state_regs(struct instruction *insn, struct insn_state *state)
10756 ++{
10757 ++ struct cfi_reg *cfa = &state->cfa;
10758 ++ struct stack_op *op = &insn->stack_op;
10759 ++
10760 ++ if (cfa->base != CFI_SP)
10761 ++ return 0;
10762 ++
10763 ++ /* push */
10764 ++ if (op->dest.type == OP_DEST_PUSH)
10765 ++ cfa->offset += 8;
10766 ++
10767 ++ /* pop */
10768 ++ if (op->src.type == OP_SRC_POP)
10769 ++ cfa->offset -= 8;
10770 ++
10771 ++ /* add immediate to sp */
10772 ++ if (op->dest.type == OP_DEST_REG && op->src.type == OP_SRC_ADD &&
10773 ++ op->dest.reg == CFI_SP && op->src.reg == CFI_SP)
10774 ++ cfa->offset -= op->src.offset;
10775 ++
10776 ++ return 0;
10777 ++}
10778 ++
10779 ++static void save_reg(struct insn_state *state, unsigned char reg, int base,
10780 ++ int offset)
10781 ++{
10782 ++ if (arch_callee_saved_reg(reg) &&
10783 ++ state->regs[reg].base == CFI_UNDEFINED) {
10784 ++ state->regs[reg].base = base;
10785 ++ state->regs[reg].offset = offset;
10786 ++ }
10787 ++}
10788 ++
10789 ++static void restore_reg(struct insn_state *state, unsigned char reg)
10790 ++{
10791 ++ state->regs[reg].base = CFI_UNDEFINED;
10792 ++ state->regs[reg].offset = 0;
10793 ++}
10794 ++
10795 ++/*
10796 ++ * A note about DRAP stack alignment:
10797 ++ *
10798 ++ * GCC has the concept of a DRAP register, which is used to help keep track of
10799 ++ * the stack pointer when aligning the stack. r10 or r13 is used as the DRAP
10800 ++ * register. The typical DRAP pattern is:
10801 ++ *
10802 ++ * 4c 8d 54 24 08 lea 0x8(%rsp),%r10
10803 ++ * 48 83 e4 c0 and $0xffffffffffffffc0,%rsp
10804 ++ * 41 ff 72 f8 pushq -0x8(%r10)
10805 ++ * 55 push %rbp
10806 ++ * 48 89 e5 mov %rsp,%rbp
10807 ++ * (more pushes)
10808 ++ * 41 52 push %r10
10809 ++ * ...
10810 ++ * 41 5a pop %r10
10811 ++ * (more pops)
10812 ++ * 5d pop %rbp
10813 ++ * 49 8d 62 f8 lea -0x8(%r10),%rsp
10814 ++ * c3 retq
10815 ++ *
10816 ++ * There are some variations in the epilogues, like:
10817 ++ *
10818 ++ * 5b pop %rbx
10819 ++ * 41 5a pop %r10
10820 ++ * 41 5c pop %r12
10821 ++ * 41 5d pop %r13
10822 ++ * 41 5e pop %r14
10823 ++ * c9 leaveq
10824 ++ * 49 8d 62 f8 lea -0x8(%r10),%rsp
10825 ++ * c3 retq
10826 ++ *
10827 ++ * and:
10828 ++ *
10829 ++ * 4c 8b 55 e8 mov -0x18(%rbp),%r10
10830 ++ * 48 8b 5d e0 mov -0x20(%rbp),%rbx
10831 ++ * 4c 8b 65 f0 mov -0x10(%rbp),%r12
10832 ++ * 4c 8b 6d f8 mov -0x8(%rbp),%r13
10833 ++ * c9 leaveq
10834 ++ * 49 8d 62 f8 lea -0x8(%r10),%rsp
10835 ++ * c3 retq
10836 ++ *
10837 ++ * Sometimes r13 is used as the DRAP register, in which case it's saved and
10838 ++ * restored beforehand:
10839 ++ *
10840 ++ * 41 55 push %r13
10841 ++ * 4c 8d 6c 24 10 lea 0x10(%rsp),%r13
10842 ++ * 48 83 e4 f0 and $0xfffffffffffffff0,%rsp
10843 ++ * ...
10844 ++ * 49 8d 65 f0 lea -0x10(%r13),%rsp
10845 ++ * 41 5d pop %r13
10846 ++ * c3 retq
10847 ++ */
10848 ++static int update_insn_state(struct instruction *insn, struct insn_state *state)
10849 ++{
10850 ++ struct stack_op *op = &insn->stack_op;
10851 ++ struct cfi_reg *cfa = &state->cfa;
10852 ++ struct cfi_reg *regs = state->regs;
10853 ++
10854 ++ /* stack operations don't make sense with an undefined CFA */
10855 ++ if (cfa->base == CFI_UNDEFINED) {
10856 ++ if (insn->func) {
10857 ++ WARN_FUNC("undefined stack state", insn->sec, insn->offset);
10858 ++ return -1;
10859 ++ }
10860 ++ return 0;
10861 ++ }
10862 ++
10863 ++ if (state->type == ORC_TYPE_REGS || state->type == ORC_TYPE_REGS_IRET)
10864 ++ return update_insn_state_regs(insn, state);
10865 ++
10866 ++ switch (op->dest.type) {
10867 ++
10868 ++ case OP_DEST_REG:
10869 ++ switch (op->src.type) {
10870 ++
10871 ++ case OP_SRC_REG:
10872 ++ if (op->src.reg == CFI_SP && op->dest.reg == CFI_BP &&
10873 ++ cfa->base == CFI_SP &&
10874 ++ regs[CFI_BP].base == CFI_CFA &&
10875 ++ regs[CFI_BP].offset == -cfa->offset) {
10876 ++
10877 ++ /* mov %rsp, %rbp */
10878 ++ cfa->base = op->dest.reg;
10879 ++ state->bp_scratch = false;
10880 ++ }
10881 ++
10882 ++ else if (op->src.reg == CFI_SP &&
10883 ++ op->dest.reg == CFI_BP && state->drap) {
10884 ++
10885 ++ /* drap: mov %rsp, %rbp */
10886 ++ regs[CFI_BP].base = CFI_BP;
10887 ++ regs[CFI_BP].offset = -state->stack_size;
10888 ++ state->bp_scratch = false;
10889 ++ }
10890 ++
10891 ++ else if (op->src.reg == CFI_SP && cfa->base == CFI_SP) {
10892 ++
10893 ++ /*
10894 ++ * mov %rsp, %reg
10895 ++ *
10896 ++ * This is needed for the rare case where GCC
10897 ++ * does:
10898 ++ *
10899 ++ * mov %rsp, %rax
10900 ++ * ...
10901 ++ * mov %rax, %rsp
10902 ++ */
10903 ++ state->vals[op->dest.reg].base = CFI_CFA;
10904 ++ state->vals[op->dest.reg].offset = -state->stack_size;
10905 ++ }
10906 ++
10907 ++ else if (op->src.reg == CFI_BP && op->dest.reg == CFI_SP &&
10908 ++ cfa->base == CFI_BP) {
10909 ++
10910 ++ /*
10911 ++ * mov %rbp, %rsp
10912 ++ *
10913 ++ * Restore the original stack pointer (Clang).
10914 ++ */
10915 ++ state->stack_size = -state->regs[CFI_BP].offset;
10916 ++ }
10917 ++
10918 ++ else if (op->dest.reg == cfa->base) {
10919 ++
10920 ++ /* mov %reg, %rsp */
10921 ++ if (cfa->base == CFI_SP &&
10922 ++ state->vals[op->src.reg].base == CFI_CFA) {
10923 ++
10924 ++ /*
10925 ++ * This is needed for the rare case
10926 ++ * where GCC does something dumb like:
10927 ++ *
10928 ++ * lea 0x8(%rsp), %rcx
10929 ++ * ...
10930 ++ * mov %rcx, %rsp
10931 ++ */
10932 ++ cfa->offset = -state->vals[op->src.reg].offset;
10933 ++ state->stack_size = cfa->offset;
10934 ++
10935 ++ } else {
10936 ++ cfa->base = CFI_UNDEFINED;
10937 ++ cfa->offset = 0;
10938 ++ }
10939 ++ }
10940 ++
10941 ++ break;
10942 ++
10943 ++ case OP_SRC_ADD:
10944 ++ if (op->dest.reg == CFI_SP && op->src.reg == CFI_SP) {
10945 ++
10946 ++ /* add imm, %rsp */
10947 ++ state->stack_size -= op->src.offset;
10948 ++ if (cfa->base == CFI_SP)
10949 ++ cfa->offset -= op->src.offset;
10950 ++ break;
10951 ++ }
10952 ++
10953 ++ if (op->dest.reg == CFI_SP && op->src.reg == CFI_BP) {
10954 ++
10955 ++ /* lea disp(%rbp), %rsp */
10956 ++ state->stack_size = -(op->src.offset + regs[CFI_BP].offset);
10957 ++ break;
10958 ++ }
10959 ++
10960 ++ if (op->src.reg == CFI_SP && cfa->base == CFI_SP) {
10961 ++
10962 ++ /* drap: lea disp(%rsp), %drap */
10963 ++ state->drap_reg = op->dest.reg;
10964 ++
10965 ++ /*
10966 ++ * lea disp(%rsp), %reg
10967 ++ *
10968 ++ * This is needed for the rare case where GCC
10969 ++ * does something dumb like:
10970 ++ *
10971 ++ * lea 0x8(%rsp), %rcx
10972 ++ * ...
10973 ++ * mov %rcx, %rsp
10974 ++ */
10975 ++ state->vals[op->dest.reg].base = CFI_CFA;
10976 ++ state->vals[op->dest.reg].offset = \
10977 ++ -state->stack_size + op->src.offset;
10978 ++
10979 ++ break;
10980 ++ }
10981 ++
10982 ++ if (state->drap && op->dest.reg == CFI_SP &&
10983 ++ op->src.reg == state->drap_reg) {
10984 ++
10985 ++ /* drap: lea disp(%drap), %rsp */
10986 ++ cfa->base = CFI_SP;
10987 ++ cfa->offset = state->stack_size = -op->src.offset;
10988 ++ state->drap_reg = CFI_UNDEFINED;
10989 ++ state->drap = false;
10990 ++ break;
10991 ++ }
10992 ++
10993 ++ if (op->dest.reg == state->cfa.base) {
10994 ++ WARN_FUNC("unsupported stack register modification",
10995 ++ insn->sec, insn->offset);
10996 ++ return -1;
10997 ++ }
10998 ++
10999 ++ break;
11000 ++
11001 ++ case OP_SRC_AND:
11002 ++ if (op->dest.reg != CFI_SP ||
11003 ++ (state->drap_reg != CFI_UNDEFINED && cfa->base != CFI_SP) ||
11004 ++ (state->drap_reg == CFI_UNDEFINED && cfa->base != CFI_BP)) {
11005 ++ WARN_FUNC("unsupported stack pointer realignment",
11006 ++ insn->sec, insn->offset);
11007 ++ return -1;
11008 ++ }
11009 ++
11010 ++ if (state->drap_reg != CFI_UNDEFINED) {
11011 ++ /* drap: and imm, %rsp */
11012 ++ cfa->base = state->drap_reg;
11013 ++ cfa->offset = state->stack_size = 0;
11014 ++ state->drap = true;
11015 ++ }
11016 ++
11017 ++ /*
11018 ++ * Older versions of GCC (4.8ish) realign the stack
11019 ++ * without DRAP, with a frame pointer.
11020 ++ */
11021 ++
11022 ++ break;
11023 ++
11024 ++ case OP_SRC_POP:
11025 ++ if (!state->drap && op->dest.type == OP_DEST_REG &&
11026 ++ op->dest.reg == cfa->base) {
11027 ++
11028 ++ /* pop %rbp */
11029 ++ cfa->base = CFI_SP;
11030 ++ }
11031 ++
11032 ++ if (state->drap && cfa->base == CFI_BP_INDIRECT &&
11033 ++ op->dest.type == OP_DEST_REG &&
11034 ++ op->dest.reg == state->drap_reg &&
11035 ++ state->drap_offset == -state->stack_size) {
11036 ++
11037 ++ /* drap: pop %drap */
11038 ++ cfa->base = state->drap_reg;
11039 ++ cfa->offset = 0;
11040 ++ state->drap_offset = -1;
11041 ++
11042 ++ } else if (regs[op->dest.reg].offset == -state->stack_size) {
11043 ++
11044 ++ /* pop %reg */
11045 ++ restore_reg(state, op->dest.reg);
11046 ++ }
11047 ++
11048 ++ state->stack_size -= 8;
11049 ++ if (cfa->base == CFI_SP)
11050 ++ cfa->offset -= 8;
11051 ++
11052 ++ break;
11053 ++
11054 ++ case OP_SRC_REG_INDIRECT:
11055 ++ if (state->drap && op->src.reg == CFI_BP &&
11056 ++ op->src.offset == state->drap_offset) {
11057 ++
11058 ++ /* drap: mov disp(%rbp), %drap */
11059 ++ cfa->base = state->drap_reg;
11060 ++ cfa->offset = 0;
11061 ++ state->drap_offset = -1;
11062 ++ }
11063 ++
11064 ++ if (state->drap && op->src.reg == CFI_BP &&
11065 ++ op->src.offset == regs[op->dest.reg].offset) {
11066 ++
11067 ++ /* drap: mov disp(%rbp), %reg */
11068 ++ restore_reg(state, op->dest.reg);
11069 ++
11070 ++ } else if (op->src.reg == cfa->base &&
11071 ++ op->src.offset == regs[op->dest.reg].offset + cfa->offset) {
11072 ++
11073 ++ /* mov disp(%rbp), %reg */
11074 ++ /* mov disp(%rsp), %reg */
11075 ++ restore_reg(state, op->dest.reg);
11076 ++ }
11077 ++
11078 ++ break;
11079 ++
11080 ++ default:
11081 ++ WARN_FUNC("unknown stack-related instruction",
11082 ++ insn->sec, insn->offset);
11083 ++ return -1;
11084 ++ }
11085 ++
11086 ++ break;
11087 ++
11088 ++ case OP_DEST_PUSH:
11089 ++ state->stack_size += 8;
11090 ++ if (cfa->base == CFI_SP)
11091 ++ cfa->offset += 8;
11092 ++
11093 ++ if (op->src.type != OP_SRC_REG)
11094 ++ break;
11095 ++
11096 ++ if (state->drap) {
11097 ++ if (op->src.reg == cfa->base && op->src.reg == state->drap_reg) {
11098 ++
11099 ++ /* drap: push %drap */
11100 ++ cfa->base = CFI_BP_INDIRECT;
11101 ++ cfa->offset = -state->stack_size;
11102 ++
11103 ++ /* save drap so we know when to restore it */
11104 ++ state->drap_offset = -state->stack_size;
11105 ++
11106 ++ } else if (op->src.reg == CFI_BP && cfa->base == state->drap_reg) {
11107 ++
11108 ++ /* drap: push %rbp */
11109 ++ state->stack_size = 0;
11110 ++
11111 ++ } else if (regs[op->src.reg].base == CFI_UNDEFINED) {
11112 ++
11113 ++ /* drap: push %reg */
11114 ++ save_reg(state, op->src.reg, CFI_BP, -state->stack_size);
11115 ++ }
11116 ++
11117 ++ } else {
11118 ++
11119 ++ /* push %reg */
11120 ++ save_reg(state, op->src.reg, CFI_CFA, -state->stack_size);
11121 ++ }
11122 ++
11123 ++ /* detect when asm code uses rbp as a scratch register */
11124 ++ if (!no_fp && insn->func && op->src.reg == CFI_BP &&
11125 ++ cfa->base != CFI_BP)
11126 ++ state->bp_scratch = true;
11127 ++ break;
11128 ++
11129 ++ case OP_DEST_REG_INDIRECT:
11130 ++
11131 ++ if (state->drap) {
11132 ++ if (op->src.reg == cfa->base && op->src.reg == state->drap_reg) {
11133 ++
11134 ++ /* drap: mov %drap, disp(%rbp) */
11135 ++ cfa->base = CFI_BP_INDIRECT;
11136 ++ cfa->offset = op->dest.offset;
11137 ++
11138 ++ /* save drap offset so we know when to restore it */
11139 ++ state->drap_offset = op->dest.offset;
11140 ++ }
11141 ++
11142 ++ else if (regs[op->src.reg].base == CFI_UNDEFINED) {
11143 ++
11144 ++ /* drap: mov reg, disp(%rbp) */
11145 ++ save_reg(state, op->src.reg, CFI_BP, op->dest.offset);
11146 ++ }
11147 ++
11148 ++ } else if (op->dest.reg == cfa->base) {
11149 ++
11150 ++ /* mov reg, disp(%rbp) */
11151 ++ /* mov reg, disp(%rsp) */
11152 ++ save_reg(state, op->src.reg, CFI_CFA,
11153 ++ op->dest.offset - state->cfa.offset);
11154 ++ }
11155 ++
11156 ++ break;
11157 ++
11158 ++ case OP_DEST_LEAVE:
11159 ++ if ((!state->drap && cfa->base != CFI_BP) ||
11160 ++ (state->drap && cfa->base != state->drap_reg)) {
11161 ++ WARN_FUNC("leave instruction with modified stack frame",
11162 ++ insn->sec, insn->offset);
11163 ++ return -1;
11164 ++ }
11165 ++
11166 ++ /* leave (mov %rbp, %rsp; pop %rbp) */
11167 ++
11168 ++ state->stack_size = -state->regs[CFI_BP].offset - 8;
11169 ++ restore_reg(state, CFI_BP);
11170 ++
11171 ++ if (!state->drap) {
11172 ++ cfa->base = CFI_SP;
11173 ++ cfa->offset -= 8;
11174 ++ }
11175 ++
11176 ++ break;
11177 ++
11178 ++ case OP_DEST_MEM:
11179 ++ if (op->src.type != OP_SRC_POP) {
11180 ++ WARN_FUNC("unknown stack-related memory operation",
11181 ++ insn->sec, insn->offset);
11182 ++ return -1;
11183 ++ }
11184 ++
11185 ++ /* pop mem */
11186 ++ state->stack_size -= 8;
11187 ++ if (cfa->base == CFI_SP)
11188 ++ cfa->offset -= 8;
11189 ++
11190 ++ break;
11191 ++
11192 ++ default:
11193 ++ WARN_FUNC("unknown stack-related instruction",
11194 ++ insn->sec, insn->offset);
11195 ++ return -1;
11196 ++ }
11197 ++
11198 ++ return 0;
11199 ++}
11200 ++
11201 ++static bool insn_state_match(struct instruction *insn, struct insn_state *state)
11202 ++{
11203 ++ struct insn_state *state1 = &insn->state, *state2 = state;
11204 ++ int i;
11205 ++
11206 ++ if (memcmp(&state1->cfa, &state2->cfa, sizeof(state1->cfa))) {
11207 ++ WARN_FUNC("stack state mismatch: cfa1=%d%+d cfa2=%d%+d",
11208 ++ insn->sec, insn->offset,
11209 ++ state1->cfa.base, state1->cfa.offset,
11210 ++ state2->cfa.base, state2->cfa.offset);
11211 ++
11212 ++ } else if (memcmp(&state1->regs, &state2->regs, sizeof(state1->regs))) {
11213 ++ for (i = 0; i < CFI_NUM_REGS; i++) {
11214 ++ if (!memcmp(&state1->regs[i], &state2->regs[i],
11215 ++ sizeof(struct cfi_reg)))
11216 ++ continue;
11217 ++
11218 ++ WARN_FUNC("stack state mismatch: reg1[%d]=%d%+d reg2[%d]=%d%+d",
11219 ++ insn->sec, insn->offset,
11220 ++ i, state1->regs[i].base, state1->regs[i].offset,
11221 ++ i, state2->regs[i].base, state2->regs[i].offset);
11222 ++ break;
11223 ++ }
11224 ++
11225 ++ } else if (state1->type != state2->type) {
11226 ++ WARN_FUNC("stack state mismatch: type1=%d type2=%d",
11227 ++ insn->sec, insn->offset, state1->type, state2->type);
11228 ++
11229 ++ } else if (state1->drap != state2->drap ||
11230 ++ (state1->drap && state1->drap_reg != state2->drap_reg) ||
11231 ++ (state1->drap && state1->drap_offset != state2->drap_offset)) {
11232 ++ WARN_FUNC("stack state mismatch: drap1=%d(%d,%d) drap2=%d(%d,%d)",
11233 ++ insn->sec, insn->offset,
11234 ++ state1->drap, state1->drap_reg, state1->drap_offset,
11235 ++ state2->drap, state2->drap_reg, state2->drap_offset);
11236 ++
11237 ++ } else
11238 ++ return true;
11239 ++
11240 ++ return false;
11241 ++}
11242 ++
11243 ++/*
11244 ++ * Follow the branch starting at the given instruction, and recursively follow
11245 ++ * any other branches (jumps). Meanwhile, track the frame pointer state at
11246 ++ * each instruction and validate all the rules described in
11247 ++ * tools/objtool/Documentation/stack-validation.txt.
11248 ++ */
11249 ++static int validate_branch(struct objtool_file *file, struct instruction *first,
11250 ++ struct insn_state state)
11251 ++{
11252 ++ struct alternative *alt;
11253 ++ struct instruction *insn, *next_insn;
11254 ++ struct section *sec;
11255 ++ struct symbol *func = NULL;
11256 ++ int ret;
11257 ++
11258 ++ insn = first;
11259 ++ sec = insn->sec;
11260 ++
11261 ++ if (insn->alt_group && list_empty(&insn->alts)) {
11262 ++ WARN_FUNC("don't know how to handle branch to middle of alternative instruction group",
11263 ++ sec, insn->offset);
11264 ++ return 1;
11265 ++ }
11266 ++
11267 ++ while (1) {
11268 ++ next_insn = next_insn_same_sec(file, insn);
11269 ++
11270 ++ if (file->c_file && func && insn->func && func != insn->func->pfunc) {
11271 ++ WARN("%s() falls through to next function %s()",
11272 ++ func->name, insn->func->name);
11273 ++ return 1;
11274 ++ }
11275 ++
11276 ++ func = insn->func ? insn->func->pfunc : NULL;
11277 ++
11278 ++ if (func && insn->ignore) {
11279 ++ WARN_FUNC("BUG: why am I validating an ignored function?",
11280 ++ sec, insn->offset);
11281 ++ return 1;
11282 ++ }
11283 ++
11284 ++ if (insn->visited) {
11285 ++ if (!insn->hint && !insn_state_match(insn, &state))
11286 ++ return 1;
11287 ++
11288 ++ return 0;
11289 ++ }
11290 ++
11291 ++ if (insn->hint) {
11292 ++ if (insn->restore) {
11293 ++ struct instruction *save_insn, *i;
11294 ++
11295 ++ i = insn;
11296 ++ save_insn = NULL;
11297 ++ func_for_each_insn_continue_reverse(file, insn->func, i) {
11298 ++ if (i->save) {
11299 ++ save_insn = i;
11300 ++ break;
11301 ++ }
11302 ++ }
11303 ++
11304 ++ if (!save_insn) {
11305 ++ WARN_FUNC("no corresponding CFI save for CFI restore",
11306 ++ sec, insn->offset);
11307 ++ return 1;
11308 ++ }
11309 ++
11310 ++ if (!save_insn->visited) {
11311 ++ /*
11312 ++ * Oops, no state to copy yet.
11313 ++ * Hopefully we can reach this
11314 ++ * instruction from another branch
11315 ++ * after the save insn has been
11316 ++ * visited.
11317 ++ */
11318 ++ if (insn == first)
11319 ++ return 0;
11320 ++
11321 ++ WARN_FUNC("objtool isn't smart enough to handle this CFI save/restore combo",
11322 ++ sec, insn->offset);
11323 ++ return 1;
11324 ++ }
11325 ++
11326 ++ insn->state = save_insn->state;
11327 ++ }
11328 ++
11329 ++ state = insn->state;
11330 ++
11331 ++ } else
11332 ++ insn->state = state;
11333 ++
11334 ++ insn->visited = true;
11335 ++
11336 ++ if (!insn->ignore_alts) {
11337 ++ list_for_each_entry(alt, &insn->alts, list) {
11338 ++ ret = validate_branch(file, alt->insn, state);
11339 ++ if (ret)
11340 ++ return 1;
11341 ++ }
11342 ++ }
11343 ++
11344 ++ switch (insn->type) {
11345 ++
11346 ++ case INSN_RETURN:
11347 ++ if (func && has_modified_stack_frame(&state)) {
11348 ++ WARN_FUNC("return with modified stack frame",
11349 ++ sec, insn->offset);
11350 ++ return 1;
11351 ++ }
11352 ++
11353 ++ if (state.bp_scratch) {
11354 ++ WARN("%s uses BP as a scratch register",
11355 ++ insn->func->name);
11356 ++ return 1;
11357 ++ }
11358 ++
11359 ++ return 0;
11360 ++
11361 ++ case INSN_CALL:
11362 ++ if (is_fentry_call(insn))
11363 ++ break;
11364 ++
11365 ++ ret = dead_end_function(file, insn->call_dest);
11366 ++ if (ret == 1)
11367 ++ return 0;
11368 ++ if (ret == -1)
11369 ++ return 1;
11370 ++
11371 ++ /* fallthrough */
11372 ++ case INSN_CALL_DYNAMIC:
11373 ++ if (!no_fp && func && !has_valid_stack_frame(&state)) {
11374 ++ WARN_FUNC("call without frame pointer save/setup",
11375 ++ sec, insn->offset);
11376 ++ return 1;
11377 ++ }
11378 ++ break;
11379 ++
11380 ++ case INSN_JUMP_CONDITIONAL:
11381 ++ case INSN_JUMP_UNCONDITIONAL:
11382 ++ if (insn->jump_dest &&
11383 ++ (!func || !insn->jump_dest->func ||
11384 ++ insn->jump_dest->func->pfunc == func)) {
11385 ++ ret = validate_branch(file, insn->jump_dest,
11386 ++ state);
11387 ++ if (ret)
11388 ++ return 1;
11389 ++
11390 ++ } else if (func && has_modified_stack_frame(&state)) {
11391 ++ WARN_FUNC("sibling call from callable instruction with modified stack frame",
11392 ++ sec, insn->offset);
11393 ++ return 1;
11394 ++ }
11395 ++
11396 ++ if (insn->type == INSN_JUMP_UNCONDITIONAL)
11397 ++ return 0;
11398 ++
11399 ++ break;
11400 ++
11401 ++ case INSN_JUMP_DYNAMIC:
11402 ++ if (func && list_empty(&insn->alts) &&
11403 ++ has_modified_stack_frame(&state)) {
11404 ++ WARN_FUNC("sibling call from callable instruction with modified stack frame",
11405 ++ sec, insn->offset);
11406 ++ return 1;
11407 ++ }
11408 ++
11409 ++ return 0;
11410 ++
11411 ++ case INSN_CONTEXT_SWITCH:
11412 ++ if (func && (!next_insn || !next_insn->hint)) {
11413 ++ WARN_FUNC("unsupported instruction in callable function",
11414 ++ sec, insn->offset);
11415 ++ return 1;
11416 ++ }
11417 ++ return 0;
11418 ++
11419 ++ case INSN_STACK:
11420 ++ if (update_insn_state(insn, &state))
11421 ++ return 1;
11422 ++
11423 ++ break;
11424 ++
11425 ++ default:
11426 ++ break;
11427 ++ }
11428 ++
11429 ++ if (insn->dead_end)
11430 ++ return 0;
11431 ++
11432 ++ if (!next_insn) {
11433 ++ if (state.cfa.base == CFI_UNDEFINED)
11434 ++ return 0;
11435 ++ WARN("%s: unexpected end of section", sec->name);
11436 ++ return 1;
11437 ++ }
11438 ++
11439 ++ insn = next_insn;
11440 ++ }
11441 ++
11442 ++ return 0;
11443 ++}
11444 ++
11445 ++static int validate_unwind_hints(struct objtool_file *file)
11446 ++{
11447 ++ struct instruction *insn;
11448 ++ int ret, warnings = 0;
11449 ++ struct insn_state state;
11450 ++
11451 ++ if (!file->hints)
11452 ++ return 0;
11453 ++
11454 ++ clear_insn_state(&state);
11455 ++
11456 ++ for_each_insn(file, insn) {
11457 ++ if (insn->hint && !insn->visited) {
11458 ++ ret = validate_branch(file, insn, state);
11459 ++ warnings += ret;
11460 ++ }
11461 ++ }
11462 ++
11463 ++ return warnings;
11464 ++}
11465 ++
11466 ++static int validate_retpoline(struct objtool_file *file)
11467 ++{
11468 ++ struct instruction *insn;
11469 ++ int warnings = 0;
11470 ++
11471 ++ for_each_insn(file, insn) {
11472 ++ if (insn->type != INSN_JUMP_DYNAMIC &&
11473 ++ insn->type != INSN_CALL_DYNAMIC)
11474 ++ continue;
11475 ++
11476 ++ if (insn->retpoline_safe)
11477 ++ continue;
11478 ++
11479 ++ /*
11480 ++ * .init.text code is ran before userspace and thus doesn't
11481 ++ * strictly need retpolines, except for modules which are
11482 ++ * loaded late, they very much do need retpoline in their
11483 ++ * .init.text
11484 ++ */
11485 ++ if (!strcmp(insn->sec->name, ".init.text") && !module)
11486 ++ continue;
11487 ++
11488 ++ WARN_FUNC("indirect %s found in RETPOLINE build",
11489 ++ insn->sec, insn->offset,
11490 ++ insn->type == INSN_JUMP_DYNAMIC ? "jump" : "call");
11491 ++
11492 ++ warnings++;
11493 ++ }
11494 ++
11495 ++ return warnings;
11496 ++}
11497 ++
11498 ++static bool is_kasan_insn(struct instruction *insn)
11499 ++{
11500 ++ return (insn->type == INSN_CALL &&
11501 ++ !strcmp(insn->call_dest->name, "__asan_handle_no_return"));
11502 ++}
11503 ++
11504 ++static bool is_ubsan_insn(struct instruction *insn)
11505 ++{
11506 ++ return (insn->type == INSN_CALL &&
11507 ++ !strcmp(insn->call_dest->name,
11508 ++ "__ubsan_handle_builtin_unreachable"));
11509 ++}
11510 ++
11511 ++static bool ignore_unreachable_insn(struct instruction *insn)
11512 ++{
11513 ++ int i;
11514 ++
11515 ++ if (insn->ignore || insn->type == INSN_NOP)
11516 ++ return true;
11517 ++
11518 ++ /*
11519 ++ * Ignore any unused exceptions. This can happen when a whitelisted
11520 ++ * function has an exception table entry.
11521 ++ *
11522 ++ * Also ignore alternative replacement instructions. This can happen
11523 ++ * when a whitelisted function uses one of the ALTERNATIVE macros.
11524 ++ */
11525 ++ if (!strcmp(insn->sec->name, ".fixup") ||
11526 ++ !strcmp(insn->sec->name, ".altinstr_replacement") ||
11527 ++ !strcmp(insn->sec->name, ".altinstr_aux"))
11528 ++ return true;
11529 ++
11530 ++ /*
11531 ++ * Check if this (or a subsequent) instruction is related to
11532 ++ * CONFIG_UBSAN or CONFIG_KASAN.
11533 ++ *
11534 ++ * End the search at 5 instructions to avoid going into the weeds.
11535 ++ */
11536 ++ if (!insn->func)
11537 ++ return false;
11538 ++ for (i = 0; i < 5; i++) {
11539 ++
11540 ++ if (is_kasan_insn(insn) || is_ubsan_insn(insn))
11541 ++ return true;
11542 ++
11543 ++ if (insn->type == INSN_JUMP_UNCONDITIONAL) {
11544 ++ if (insn->jump_dest &&
11545 ++ insn->jump_dest->func == insn->func) {
11546 ++ insn = insn->jump_dest;
11547 ++ continue;
11548 ++ }
11549 ++
11550 ++ break;
11551 ++ }
11552 ++
11553 ++ if (insn->offset + insn->len >= insn->func->offset + insn->func->len)
11554 ++ break;
11555 ++
11556 ++ insn = list_next_entry(insn, list);
11557 ++ }
11558 ++
11559 ++ return false;
11560 ++}
11561 ++
11562 ++static int validate_functions(struct objtool_file *file)
11563 ++{
11564 ++ struct section *sec;
11565 ++ struct symbol *func;
11566 ++ struct instruction *insn;
11567 ++ struct insn_state state;
11568 ++ int ret, warnings = 0;
11569 ++
11570 ++ clear_insn_state(&state);
11571 ++
11572 ++ state.cfa = initial_func_cfi.cfa;
11573 ++ memcpy(&state.regs, &initial_func_cfi.regs,
11574 ++ CFI_NUM_REGS * sizeof(struct cfi_reg));
11575 ++ state.stack_size = initial_func_cfi.cfa.offset;
11576 ++
11577 ++ for_each_sec(file, sec) {
11578 ++ list_for_each_entry(func, &sec->symbol_list, list) {
11579 ++ if (func->type != STT_FUNC || func->pfunc != func)
11580 ++ continue;
11581 ++
11582 ++ insn = find_insn(file, sec, func->offset);
11583 ++ if (!insn || insn->ignore)
11584 ++ continue;
11585 ++
11586 ++ ret = validate_branch(file, insn, state);
11587 ++ warnings += ret;
11588 ++ }
11589 ++ }
11590 ++
11591 ++ return warnings;
11592 ++}
11593 ++
11594 ++static int validate_reachable_instructions(struct objtool_file *file)
11595 ++{
11596 ++ struct instruction *insn;
11597 ++
11598 ++ if (file->ignore_unreachables)
11599 ++ return 0;
11600 ++
11601 ++ for_each_insn(file, insn) {
11602 ++ if (insn->visited || ignore_unreachable_insn(insn))
11603 ++ continue;
11604 ++
11605 ++ WARN_FUNC("unreachable instruction", insn->sec, insn->offset);
11606 ++ return 1;
11607 ++ }
11608 ++
11609 ++ return 0;
11610 ++}
11611 ++
11612 ++static void cleanup(struct objtool_file *file)
11613 ++{
11614 ++ struct instruction *insn, *tmpinsn;
11615 ++ struct alternative *alt, *tmpalt;
11616 ++
11617 ++ list_for_each_entry_safe(insn, tmpinsn, &file->insn_list, list) {
11618 ++ list_for_each_entry_safe(alt, tmpalt, &insn->alts, list) {
11619 ++ list_del(&alt->list);
11620 ++ free(alt);
11621 ++ }
11622 ++ list_del(&insn->list);
11623 ++ hash_del(&insn->hash);
11624 ++ free(insn);
11625 ++ }
11626 ++ elf_close(file->elf);
11627 ++}
11628 ++
11629 ++int check(const char *_objname, bool orc)
11630 ++{
11631 ++ struct objtool_file file;
11632 ++ int ret, warnings = 0;
11633 ++
11634 ++ objname = _objname;
11635 ++
11636 ++ file.elf = elf_open(objname, orc ? O_RDWR : O_RDONLY);
11637 ++ if (!file.elf)
11638 ++ return 1;
11639 ++
11640 ++ INIT_LIST_HEAD(&file.insn_list);
11641 ++ hash_init(file.insn_hash);
11642 ++ file.whitelist = find_section_by_name(file.elf, ".discard.func_stack_frame_non_standard");
11643 ++ file.rodata = find_section_by_name(file.elf, ".rodata");
11644 ++ file.c_file = find_section_by_name(file.elf, ".comment");
11645 ++ file.ignore_unreachables = no_unreachable;
11646 ++ file.hints = false;
11647 ++
11648 ++ arch_initial_func_cfi_state(&initial_func_cfi);
11649 ++
11650 ++ ret = decode_sections(&file);
11651 ++ if (ret < 0)
11652 ++ goto out;
11653 ++ warnings += ret;
11654 ++
11655 ++ if (list_empty(&file.insn_list))
11656 ++ goto out;
11657 ++
11658 ++ if (retpoline) {
11659 ++ ret = validate_retpoline(&file);
11660 ++ if (ret < 0)
11661 ++ return ret;
11662 ++ warnings += ret;
11663 ++ }
11664 ++
11665 ++ ret = validate_functions(&file);
11666 ++ if (ret < 0)
11667 ++ goto out;
11668 ++ warnings += ret;
11669 ++
11670 ++ ret = validate_unwind_hints(&file);
11671 ++ if (ret < 0)
11672 ++ goto out;
11673 ++ warnings += ret;
11674 ++
11675 ++ if (!warnings) {
11676 ++ ret = validate_reachable_instructions(&file);
11677 ++ if (ret < 0)
11678 ++ goto out;
11679 ++ warnings += ret;
11680 ++ }
11681 ++
11682 ++ if (orc) {
11683 ++ ret = create_orc(&file);
11684 ++ if (ret < 0)
11685 ++ goto out;
11686 ++
11687 ++ ret = create_orc_sections(&file);
11688 ++ if (ret < 0)
11689 ++ goto out;
11690 ++
11691 ++ ret = elf_write(file.elf);
11692 ++ if (ret < 0)
11693 ++ goto out;
11694 ++ }
11695 ++
11696 ++out:
11697 ++ cleanup(&file);
11698 ++
11699 ++ /* ignore warnings for now until we get all the code cleaned up */
11700 ++ if (ret || warnings)
11701 ++ return 0;
11702 ++ return 0;
11703 ++}
11704 +diff --git a/tools/objtool/check.h b/tools/objtool/check.h
11705 +new file mode 100644
11706 +index 000000000000..c6b68fcb926f
11707 +--- /dev/null
11708 ++++ b/tools/objtool/check.h
11709 +@@ -0,0 +1,82 @@
11710 ++/*
11711 ++ * Copyright (C) 2017 Josh Poimboeuf <jpoimboe@××××××.com>
11712 ++ *
11713 ++ * This program is free software; you can redistribute it and/or
11714 ++ * modify it under the terms of the GNU General Public License
11715 ++ * as published by the Free Software Foundation; either version 2
11716 ++ * of the License, or (at your option) any later version.
11717 ++ *
11718 ++ * This program is distributed in the hope that it will be useful,
11719 ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11720 ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11721 ++ * GNU General Public License for more details.
11722 ++ *
11723 ++ * You should have received a copy of the GNU General Public License
11724 ++ * along with this program; if not, see <http://www.gnu.org/licenses/>.
11725 ++ */
11726 ++
11727 ++#ifndef _CHECK_H
11728 ++#define _CHECK_H
11729 ++
11730 ++#include <stdbool.h>
11731 ++#include "elf.h"
11732 ++#include "cfi.h"
11733 ++#include "arch.h"
11734 ++#include "orc.h"
11735 ++#include <linux/hashtable.h>
11736 ++
11737 ++struct insn_state {
11738 ++ struct cfi_reg cfa;
11739 ++ struct cfi_reg regs[CFI_NUM_REGS];
11740 ++ int stack_size;
11741 ++ unsigned char type;
11742 ++ bool bp_scratch;
11743 ++ bool drap;
11744 ++ int drap_reg, drap_offset;
11745 ++ struct cfi_reg vals[CFI_NUM_REGS];
11746 ++};
11747 ++
11748 ++struct instruction {
11749 ++ struct list_head list;
11750 ++ struct hlist_node hash;
11751 ++ struct section *sec;
11752 ++ unsigned long offset;
11753 ++ unsigned int len;
11754 ++ unsigned char type;
11755 ++ unsigned long immediate;
11756 ++ bool alt_group, visited, dead_end, ignore, hint, save, restore, ignore_alts;
11757 ++ bool retpoline_safe;
11758 ++ struct symbol *call_dest;
11759 ++ struct instruction *jump_dest;
11760 ++ struct instruction *first_jump_src;
11761 ++ struct list_head alts;
11762 ++ struct symbol *func;
11763 ++ struct stack_op stack_op;
11764 ++ struct insn_state state;
11765 ++ struct orc_entry orc;
11766 ++};
11767 ++
11768 ++struct objtool_file {
11769 ++ struct elf *elf;
11770 ++ struct list_head insn_list;
11771 ++ DECLARE_HASHTABLE(insn_hash, 16);
11772 ++ struct section *rodata, *whitelist;
11773 ++ bool ignore_unreachables, c_file, hints;
11774 ++};
11775 ++
11776 ++int check(const char *objname, bool orc);
11777 ++
11778 ++struct instruction *find_insn(struct objtool_file *file,
11779 ++ struct section *sec, unsigned long offset);
11780 ++
11781 ++#define for_each_insn(file, insn) \
11782 ++ list_for_each_entry(insn, &file->insn_list, list)
11783 ++
11784 ++#define sec_for_each_insn(file, sec, insn) \
11785 ++ for (insn = find_insn(file, sec, 0); \
11786 ++ insn && &insn->list != &file->insn_list && \
11787 ++ insn->sec == sec; \
11788 ++ insn = list_next_entry(insn, list))
11789 ++
11790 ++
11791 ++#endif /* _CHECK_H */
11792 +diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c
11793 +index faacf0c89976..4e60e105583e 100644
11794 +--- a/tools/objtool/elf.c
11795 ++++ b/tools/objtool/elf.c
11796 +@@ -31,13 +31,6 @@
11797 + #include "elf.h"
11798 + #include "warn.h"
11799 +
11800 +-/*
11801 +- * Fallback for systems without this "read, mmaping if possible" cmd.
11802 +- */
11803 +-#ifndef ELF_C_READ_MMAP
11804 +-#define ELF_C_READ_MMAP ELF_C_READ
11805 +-#endif
11806 +-
11807 + struct section *find_section_by_name(struct elf *elf, const char *name)
11808 + {
11809 + struct section *sec;
11810 +@@ -86,6 +79,19 @@ struct symbol *find_symbol_by_offset(struct section *sec, unsigned long offset)
11811 + return NULL;
11812 + }
11813 +
11814 ++struct symbol *find_symbol_by_name(struct elf *elf, const char *name)
11815 ++{
11816 ++ struct section *sec;
11817 ++ struct symbol *sym;
11818 ++
11819 ++ list_for_each_entry(sec, &elf->sections, list)
11820 ++ list_for_each_entry(sym, &sec->symbol_list, list)
11821 ++ if (!strcmp(sym->name, name))
11822 ++ return sym;
11823 ++
11824 ++ return NULL;
11825 ++}
11826 ++
11827 + struct symbol *find_symbol_containing(struct section *sec, unsigned long offset)
11828 + {
11829 + struct symbol *sym;
11830 +@@ -140,12 +146,12 @@ static int read_sections(struct elf *elf)
11831 + int i;
11832 +
11833 + if (elf_getshdrnum(elf->elf, &sections_nr)) {
11834 +- perror("elf_getshdrnum");
11835 ++ WARN_ELF("elf_getshdrnum");
11836 + return -1;
11837 + }
11838 +
11839 + if (elf_getshdrstrndx(elf->elf, &shstrndx)) {
11840 +- perror("elf_getshdrstrndx");
11841 ++ WARN_ELF("elf_getshdrstrndx");
11842 + return -1;
11843 + }
11844 +
11845 +@@ -166,37 +172,37 @@ static int read_sections(struct elf *elf)
11846 +
11847 + s = elf_getscn(elf->elf, i);
11848 + if (!s) {
11849 +- perror("elf_getscn");
11850 ++ WARN_ELF("elf_getscn");
11851 + return -1;
11852 + }
11853 +
11854 + sec->idx = elf_ndxscn(s);
11855 +
11856 + if (!gelf_getshdr(s, &sec->sh)) {
11857 +- perror("gelf_getshdr");
11858 ++ WARN_ELF("gelf_getshdr");
11859 + return -1;
11860 + }
11861 +
11862 + sec->name = elf_strptr(elf->elf, shstrndx, sec->sh.sh_name);
11863 + if (!sec->name) {
11864 +- perror("elf_strptr");
11865 ++ WARN_ELF("elf_strptr");
11866 + return -1;
11867 + }
11868 +
11869 +- sec->elf_data = elf_getdata(s, NULL);
11870 +- if (!sec->elf_data) {
11871 +- perror("elf_getdata");
11872 +- return -1;
11873 +- }
11874 +-
11875 +- if (sec->elf_data->d_off != 0 ||
11876 +- sec->elf_data->d_size != sec->sh.sh_size) {
11877 +- WARN("unexpected data attributes for %s", sec->name);
11878 +- return -1;
11879 ++ if (sec->sh.sh_size != 0) {
11880 ++ sec->data = elf_getdata(s, NULL);
11881 ++ if (!sec->data) {
11882 ++ WARN_ELF("elf_getdata");
11883 ++ return -1;
11884 ++ }
11885 ++ if (sec->data->d_off != 0 ||
11886 ++ sec->data->d_size != sec->sh.sh_size) {
11887 ++ WARN("unexpected data attributes for %s",
11888 ++ sec->name);
11889 ++ return -1;
11890 ++ }
11891 + }
11892 +-
11893 +- sec->data = (unsigned long)sec->elf_data->d_buf;
11894 +- sec->len = sec->elf_data->d_size;
11895 ++ sec->len = sec->sh.sh_size;
11896 + }
11897 +
11898 + /* sanity check, one more call to elf_nextscn() should return NULL */
11899 +@@ -210,10 +216,11 @@ static int read_sections(struct elf *elf)
11900 +
11901 + static int read_symbols(struct elf *elf)
11902 + {
11903 +- struct section *symtab;
11904 +- struct symbol *sym;
11905 ++ struct section *symtab, *sec;
11906 ++ struct symbol *sym, *pfunc;
11907 + struct list_head *entry, *tmp;
11908 + int symbols_nr, i;
11909 ++ char *coldstr;
11910 +
11911 + symtab = find_section_by_name(elf, ".symtab");
11912 + if (!symtab) {
11913 +@@ -233,15 +240,15 @@ static int read_symbols(struct elf *elf)
11914 +
11915 + sym->idx = i;
11916 +
11917 +- if (!gelf_getsym(symtab->elf_data, i, &sym->sym)) {
11918 +- perror("gelf_getsym");
11919 ++ if (!gelf_getsym(symtab->data, i, &sym->sym)) {
11920 ++ WARN_ELF("gelf_getsym");
11921 + goto err;
11922 + }
11923 +
11924 + sym->name = elf_strptr(elf->elf, symtab->sh.sh_link,
11925 + sym->sym.st_name);
11926 + if (!sym->name) {
11927 +- perror("elf_strptr");
11928 ++ WARN_ELF("elf_strptr");
11929 + goto err;
11930 + }
11931 +
11932 +@@ -288,6 +295,30 @@ static int read_symbols(struct elf *elf)
11933 + hash_add(sym->sec->symbol_hash, &sym->hash, sym->idx);
11934 + }
11935 +
11936 ++ /* Create parent/child links for any cold subfunctions */
11937 ++ list_for_each_entry(sec, &elf->sections, list) {
11938 ++ list_for_each_entry(sym, &sec->symbol_list, list) {
11939 ++ if (sym->type != STT_FUNC)
11940 ++ continue;
11941 ++ sym->pfunc = sym->cfunc = sym;
11942 ++ coldstr = strstr(sym->name, ".cold.");
11943 ++ if (coldstr) {
11944 ++ coldstr[0] = '\0';
11945 ++ pfunc = find_symbol_by_name(elf, sym->name);
11946 ++ coldstr[0] = '.';
11947 ++
11948 ++ if (!pfunc) {
11949 ++ WARN("%s(): can't find parent function",
11950 ++ sym->name);
11951 ++ goto err;
11952 ++ }
11953 ++
11954 ++ sym->pfunc = pfunc;
11955 ++ pfunc->cfunc = sym;
11956 ++ }
11957 ++ }
11958 ++ }
11959 ++
11960 + return 0;
11961 +
11962 + err:
11963 +@@ -323,8 +354,8 @@ static int read_relas(struct elf *elf)
11964 + }
11965 + memset(rela, 0, sizeof(*rela));
11966 +
11967 +- if (!gelf_getrela(sec->elf_data, i, &rela->rela)) {
11968 +- perror("gelf_getrela");
11969 ++ if (!gelf_getrela(sec->data, i, &rela->rela)) {
11970 ++ WARN_ELF("gelf_getrela");
11971 + return -1;
11972 + }
11973 +
11974 +@@ -348,9 +379,10 @@ static int read_relas(struct elf *elf)
11975 + return 0;
11976 + }
11977 +
11978 +-struct elf *elf_open(const char *name)
11979 ++struct elf *elf_open(const char *name, int flags)
11980 + {
11981 + struct elf *elf;
11982 ++ Elf_Cmd cmd;
11983 +
11984 + elf_version(EV_CURRENT);
11985 +
11986 +@@ -363,27 +395,28 @@ struct elf *elf_open(const char *name)
11987 +
11988 + INIT_LIST_HEAD(&elf->sections);
11989 +
11990 +- elf->name = strdup(name);
11991 +- if (!elf->name) {
11992 +- perror("strdup");
11993 +- goto err;
11994 +- }
11995 +-
11996 +- elf->fd = open(name, O_RDONLY);
11997 ++ elf->fd = open(name, flags);
11998 + if (elf->fd == -1) {
11999 + fprintf(stderr, "objtool: Can't open '%s': %s\n",
12000 + name, strerror(errno));
12001 + goto err;
12002 + }
12003 +
12004 +- elf->elf = elf_begin(elf->fd, ELF_C_READ_MMAP, NULL);
12005 ++ if ((flags & O_ACCMODE) == O_RDONLY)
12006 ++ cmd = ELF_C_READ_MMAP;
12007 ++ else if ((flags & O_ACCMODE) == O_RDWR)
12008 ++ cmd = ELF_C_RDWR;
12009 ++ else /* O_WRONLY */
12010 ++ cmd = ELF_C_WRITE;
12011 ++
12012 ++ elf->elf = elf_begin(elf->fd, cmd, NULL);
12013 + if (!elf->elf) {
12014 +- perror("elf_begin");
12015 ++ WARN_ELF("elf_begin");
12016 + goto err;
12017 + }
12018 +
12019 + if (!gelf_getehdr(elf->elf, &elf->ehdr)) {
12020 +- perror("gelf_getehdr");
12021 ++ WARN_ELF("gelf_getehdr");
12022 + goto err;
12023 + }
12024 +
12025 +@@ -403,12 +436,212 @@ struct elf *elf_open(const char *name)
12026 + return NULL;
12027 + }
12028 +
12029 ++struct section *elf_create_section(struct elf *elf, const char *name,
12030 ++ size_t entsize, int nr)
12031 ++{
12032 ++ struct section *sec, *shstrtab;
12033 ++ size_t size = entsize * nr;
12034 ++ struct Elf_Scn *s;
12035 ++ Elf_Data *data;
12036 ++
12037 ++ sec = malloc(sizeof(*sec));
12038 ++ if (!sec) {
12039 ++ perror("malloc");
12040 ++ return NULL;
12041 ++ }
12042 ++ memset(sec, 0, sizeof(*sec));
12043 ++
12044 ++ INIT_LIST_HEAD(&sec->symbol_list);
12045 ++ INIT_LIST_HEAD(&sec->rela_list);
12046 ++ hash_init(sec->rela_hash);
12047 ++ hash_init(sec->symbol_hash);
12048 ++
12049 ++ list_add_tail(&sec->list, &elf->sections);
12050 ++
12051 ++ s = elf_newscn(elf->elf);
12052 ++ if (!s) {
12053 ++ WARN_ELF("elf_newscn");
12054 ++ return NULL;
12055 ++ }
12056 ++
12057 ++ sec->name = strdup(name);
12058 ++ if (!sec->name) {
12059 ++ perror("strdup");
12060 ++ return NULL;
12061 ++ }
12062 ++
12063 ++ sec->idx = elf_ndxscn(s);
12064 ++ sec->len = size;
12065 ++ sec->changed = true;
12066 ++
12067 ++ sec->data = elf_newdata(s);
12068 ++ if (!sec->data) {
12069 ++ WARN_ELF("elf_newdata");
12070 ++ return NULL;
12071 ++ }
12072 ++
12073 ++ sec->data->d_size = size;
12074 ++ sec->data->d_align = 1;
12075 ++
12076 ++ if (size) {
12077 ++ sec->data->d_buf = malloc(size);
12078 ++ if (!sec->data->d_buf) {
12079 ++ perror("malloc");
12080 ++ return NULL;
12081 ++ }
12082 ++ memset(sec->data->d_buf, 0, size);
12083 ++ }
12084 ++
12085 ++ if (!gelf_getshdr(s, &sec->sh)) {
12086 ++ WARN_ELF("gelf_getshdr");
12087 ++ return NULL;
12088 ++ }
12089 ++
12090 ++ sec->sh.sh_size = size;
12091 ++ sec->sh.sh_entsize = entsize;
12092 ++ sec->sh.sh_type = SHT_PROGBITS;
12093 ++ sec->sh.sh_addralign = 1;
12094 ++ sec->sh.sh_flags = SHF_ALLOC;
12095 ++
12096 ++
12097 ++ /* Add section name to .shstrtab */
12098 ++ shstrtab = find_section_by_name(elf, ".shstrtab");
12099 ++ if (!shstrtab) {
12100 ++ WARN("can't find .shstrtab section");
12101 ++ return NULL;
12102 ++ }
12103 ++
12104 ++ s = elf_getscn(elf->elf, shstrtab->idx);
12105 ++ if (!s) {
12106 ++ WARN_ELF("elf_getscn");
12107 ++ return NULL;
12108 ++ }
12109 ++
12110 ++ data = elf_newdata(s);
12111 ++ if (!data) {
12112 ++ WARN_ELF("elf_newdata");
12113 ++ return NULL;
12114 ++ }
12115 ++
12116 ++ data->d_buf = sec->name;
12117 ++ data->d_size = strlen(name) + 1;
12118 ++ data->d_align = 1;
12119 ++
12120 ++ sec->sh.sh_name = shstrtab->len;
12121 ++
12122 ++ shstrtab->len += strlen(name) + 1;
12123 ++ shstrtab->changed = true;
12124 ++
12125 ++ return sec;
12126 ++}
12127 ++
12128 ++struct section *elf_create_rela_section(struct elf *elf, struct section *base)
12129 ++{
12130 ++ char *relaname;
12131 ++ struct section *sec;
12132 ++
12133 ++ relaname = malloc(strlen(base->name) + strlen(".rela") + 1);
12134 ++ if (!relaname) {
12135 ++ perror("malloc");
12136 ++ return NULL;
12137 ++ }
12138 ++ strcpy(relaname, ".rela");
12139 ++ strcat(relaname, base->name);
12140 ++
12141 ++ sec = elf_create_section(elf, relaname, sizeof(GElf_Rela), 0);
12142 ++ free(relaname);
12143 ++ if (!sec)
12144 ++ return NULL;
12145 ++
12146 ++ base->rela = sec;
12147 ++ sec->base = base;
12148 ++
12149 ++ sec->sh.sh_type = SHT_RELA;
12150 ++ sec->sh.sh_addralign = 8;
12151 ++ sec->sh.sh_link = find_section_by_name(elf, ".symtab")->idx;
12152 ++ sec->sh.sh_info = base->idx;
12153 ++ sec->sh.sh_flags = SHF_INFO_LINK;
12154 ++
12155 ++ return sec;
12156 ++}
12157 ++
12158 ++int elf_rebuild_rela_section(struct section *sec)
12159 ++{
12160 ++ struct rela *rela;
12161 ++ int nr, idx = 0, size;
12162 ++ GElf_Rela *relas;
12163 ++
12164 ++ nr = 0;
12165 ++ list_for_each_entry(rela, &sec->rela_list, list)
12166 ++ nr++;
12167 ++
12168 ++ size = nr * sizeof(*relas);
12169 ++ relas = malloc(size);
12170 ++ if (!relas) {
12171 ++ perror("malloc");
12172 ++ return -1;
12173 ++ }
12174 ++
12175 ++ sec->data->d_buf = relas;
12176 ++ sec->data->d_size = size;
12177 ++
12178 ++ sec->sh.sh_size = size;
12179 ++
12180 ++ idx = 0;
12181 ++ list_for_each_entry(rela, &sec->rela_list, list) {
12182 ++ relas[idx].r_offset = rela->offset;
12183 ++ relas[idx].r_addend = rela->addend;
12184 ++ relas[idx].r_info = GELF_R_INFO(rela->sym->idx, rela->type);
12185 ++ idx++;
12186 ++ }
12187 ++
12188 ++ return 0;
12189 ++}
12190 ++
12191 ++int elf_write(struct elf *elf)
12192 ++{
12193 ++ struct section *sec;
12194 ++ Elf_Scn *s;
12195 ++
12196 ++ /* Update section headers for changed sections: */
12197 ++ list_for_each_entry(sec, &elf->sections, list) {
12198 ++ if (sec->changed) {
12199 ++ s = elf_getscn(elf->elf, sec->idx);
12200 ++ if (!s) {
12201 ++ WARN_ELF("elf_getscn");
12202 ++ return -1;
12203 ++ }
12204 ++ if (!gelf_update_shdr(s, &sec->sh)) {
12205 ++ WARN_ELF("gelf_update_shdr");
12206 ++ return -1;
12207 ++ }
12208 ++ }
12209 ++ }
12210 ++
12211 ++ /* Make sure the new section header entries get updated properly. */
12212 ++ elf_flagelf(elf->elf, ELF_C_SET, ELF_F_DIRTY);
12213 ++
12214 ++ /* Write all changes to the file. */
12215 ++ if (elf_update(elf->elf, ELF_C_WRITE) < 0) {
12216 ++ WARN_ELF("elf_update");
12217 ++ return -1;
12218 ++ }
12219 ++
12220 ++ return 0;
12221 ++}
12222 ++
12223 + void elf_close(struct elf *elf)
12224 + {
12225 + struct section *sec, *tmpsec;
12226 + struct symbol *sym, *tmpsym;
12227 + struct rela *rela, *tmprela;
12228 +
12229 ++ if (elf->elf)
12230 ++ elf_end(elf->elf);
12231 ++
12232 ++ if (elf->fd > 0)
12233 ++ close(elf->fd);
12234 ++
12235 + list_for_each_entry_safe(sec, tmpsec, &elf->sections, list) {
12236 + list_for_each_entry_safe(sym, tmpsym, &sec->symbol_list, list) {
12237 + list_del(&sym->list);
12238 +@@ -423,11 +656,6 @@ void elf_close(struct elf *elf)
12239 + list_del(&sec->list);
12240 + free(sec);
12241 + }
12242 +- if (elf->name)
12243 +- free(elf->name);
12244 +- if (elf->fd > 0)
12245 +- close(elf->fd);
12246 +- if (elf->elf)
12247 +- elf_end(elf->elf);
12248 ++
12249 + free(elf);
12250 + }
12251 +diff --git a/tools/objtool/elf.h b/tools/objtool/elf.h
12252 +index 731973e1a3f5..de5cd2ddded9 100644
12253 +--- a/tools/objtool/elf.h
12254 ++++ b/tools/objtool/elf.h
12255 +@@ -28,6 +28,13 @@
12256 + # define elf_getshdrstrndx elf_getshstrndx
12257 + #endif
12258 +
12259 ++/*
12260 ++ * Fallback for systems without this "read, mmaping if possible" cmd.
12261 ++ */
12262 ++#ifndef ELF_C_READ_MMAP
12263 ++#define ELF_C_READ_MMAP ELF_C_READ
12264 ++#endif
12265 ++
12266 + struct section {
12267 + struct list_head list;
12268 + GElf_Shdr sh;
12269 +@@ -37,11 +44,11 @@ struct section {
12270 + DECLARE_HASHTABLE(rela_hash, 16);
12271 + struct section *base, *rela;
12272 + struct symbol *sym;
12273 +- Elf_Data *elf_data;
12274 ++ Elf_Data *data;
12275 + char *name;
12276 + int idx;
12277 +- unsigned long data;
12278 + unsigned int len;
12279 ++ bool changed, text;
12280 + };
12281 +
12282 + struct symbol {
12283 +@@ -54,6 +61,7 @@ struct symbol {
12284 + unsigned char bind, type;
12285 + unsigned long offset;
12286 + unsigned int len;
12287 ++ struct symbol *pfunc, *cfunc;
12288 + };
12289 +
12290 + struct rela {
12291 +@@ -76,16 +84,23 @@ struct elf {
12292 + };
12293 +
12294 +
12295 +-struct elf *elf_open(const char *name);
12296 ++struct elf *elf_open(const char *name, int flags);
12297 + struct section *find_section_by_name(struct elf *elf, const char *name);
12298 + struct symbol *find_symbol_by_offset(struct section *sec, unsigned long offset);
12299 ++struct symbol *find_symbol_by_name(struct elf *elf, const char *name);
12300 + struct symbol *find_symbol_containing(struct section *sec, unsigned long offset);
12301 + struct rela *find_rela_by_dest(struct section *sec, unsigned long offset);
12302 + struct rela *find_rela_by_dest_range(struct section *sec, unsigned long offset,
12303 + unsigned int len);
12304 + struct symbol *find_containing_func(struct section *sec, unsigned long offset);
12305 ++struct section *elf_create_section(struct elf *elf, const char *name, size_t
12306 ++ entsize, int nr);
12307 ++struct section *elf_create_rela_section(struct elf *elf, struct section *base);
12308 ++int elf_rebuild_rela_section(struct section *sec);
12309 ++int elf_write(struct elf *elf);
12310 + void elf_close(struct elf *elf);
12311 +
12312 +-
12313 ++#define for_each_sec(file, sec) \
12314 ++ list_for_each_entry(sec, &file->elf->sections, list)
12315 +
12316 + #endif /* _OBJTOOL_ELF_H */
12317 +diff --git a/tools/objtool/objtool.c b/tools/objtool/objtool.c
12318 +index 46c326db4f46..07f329919828 100644
12319 +--- a/tools/objtool/objtool.c
12320 ++++ b/tools/objtool/objtool.c
12321 +@@ -31,11 +31,10 @@
12322 + #include <stdlib.h>
12323 + #include <subcmd/exec-cmd.h>
12324 + #include <subcmd/pager.h>
12325 ++#include <linux/kernel.h>
12326 +
12327 + #include "builtin.h"
12328 +
12329 +-#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
12330 +-
12331 + struct cmd_struct {
12332 + const char *name;
12333 + int (*fn)(int, const char **);
12334 +@@ -43,10 +42,11 @@ struct cmd_struct {
12335 + };
12336 +
12337 + static const char objtool_usage_string[] =
12338 +- "objtool [OPTIONS] COMMAND [ARGS]";
12339 ++ "objtool COMMAND [ARGS]";
12340 +
12341 + static struct cmd_struct objtool_cmds[] = {
12342 + {"check", cmd_check, "Perform stack metadata validation on an object file" },
12343 ++ {"orc", cmd_orc, "Generate in-place ORC unwind tables for an object file" },
12344 + };
12345 +
12346 + bool help;
12347 +@@ -70,7 +70,7 @@ static void cmd_usage(void)
12348 +
12349 + printf("\n");
12350 +
12351 +- exit(1);
12352 ++ exit(129);
12353 + }
12354 +
12355 + static void handle_options(int *argc, const char ***argv)
12356 +@@ -86,9 +86,7 @@ static void handle_options(int *argc, const char ***argv)
12357 + break;
12358 + } else {
12359 + fprintf(stderr, "Unknown option: %s\n", cmd);
12360 +- fprintf(stderr, "\n Usage: %s\n",
12361 +- objtool_usage_string);
12362 +- exit(1);
12363 ++ cmd_usage();
12364 + }
12365 +
12366 + (*argv)++;
12367 +diff --git a/tools/objtool/orc.h b/tools/objtool/orc.h
12368 +new file mode 100644
12369 +index 000000000000..b0e92a6d0903
12370 +--- /dev/null
12371 ++++ b/tools/objtool/orc.h
12372 +@@ -0,0 +1,30 @@
12373 ++/*
12374 ++ * Copyright (C) 2017 Josh Poimboeuf <jpoimboe@××××××.com>
12375 ++ *
12376 ++ * This program is free software; you can redistribute it and/or
12377 ++ * modify it under the terms of the GNU General Public License
12378 ++ * as published by the Free Software Foundation; either version 2
12379 ++ * of the License, or (at your option) any later version.
12380 ++ *
12381 ++ * This program is distributed in the hope that it will be useful,
12382 ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12383 ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12384 ++ * GNU General Public License for more details.
12385 ++ *
12386 ++ * You should have received a copy of the GNU General Public License
12387 ++ * along with this program; if not, see <http://www.gnu.org/licenses/>.
12388 ++ */
12389 ++
12390 ++#ifndef _ORC_H
12391 ++#define _ORC_H
12392 ++
12393 ++#include <asm/orc_types.h>
12394 ++
12395 ++struct objtool_file;
12396 ++
12397 ++int create_orc(struct objtool_file *file);
12398 ++int create_orc_sections(struct objtool_file *file);
12399 ++
12400 ++int orc_dump(const char *objname);
12401 ++
12402 ++#endif /* _ORC_H */
12403 +diff --git a/tools/objtool/orc_dump.c b/tools/objtool/orc_dump.c
12404 +new file mode 100644
12405 +index 000000000000..c3343820916a
12406 +--- /dev/null
12407 ++++ b/tools/objtool/orc_dump.c
12408 +@@ -0,0 +1,213 @@
12409 ++/*
12410 ++ * Copyright (C) 2017 Josh Poimboeuf <jpoimboe@××××××.com>
12411 ++ *
12412 ++ * This program is free software; you can redistribute it and/or
12413 ++ * modify it under the terms of the GNU General Public License
12414 ++ * as published by the Free Software Foundation; either version 2
12415 ++ * of the License, or (at your option) any later version.
12416 ++ *
12417 ++ * This program is distributed in the hope that it will be useful,
12418 ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12419 ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12420 ++ * GNU General Public License for more details.
12421 ++ *
12422 ++ * You should have received a copy of the GNU General Public License
12423 ++ * along with this program; if not, see <http://www.gnu.org/licenses/>.
12424 ++ */
12425 ++
12426 ++#include <unistd.h>
12427 ++#include "orc.h"
12428 ++#include "warn.h"
12429 ++
12430 ++static const char *reg_name(unsigned int reg)
12431 ++{
12432 ++ switch (reg) {
12433 ++ case ORC_REG_PREV_SP:
12434 ++ return "prevsp";
12435 ++ case ORC_REG_DX:
12436 ++ return "dx";
12437 ++ case ORC_REG_DI:
12438 ++ return "di";
12439 ++ case ORC_REG_BP:
12440 ++ return "bp";
12441 ++ case ORC_REG_SP:
12442 ++ return "sp";
12443 ++ case ORC_REG_R10:
12444 ++ return "r10";
12445 ++ case ORC_REG_R13:
12446 ++ return "r13";
12447 ++ case ORC_REG_BP_INDIRECT:
12448 ++ return "bp(ind)";
12449 ++ case ORC_REG_SP_INDIRECT:
12450 ++ return "sp(ind)";
12451 ++ default:
12452 ++ return "?";
12453 ++ }
12454 ++}
12455 ++
12456 ++static const char *orc_type_name(unsigned int type)
12457 ++{
12458 ++ switch (type) {
12459 ++ case ORC_TYPE_CALL:
12460 ++ return "call";
12461 ++ case ORC_TYPE_REGS:
12462 ++ return "regs";
12463 ++ case ORC_TYPE_REGS_IRET:
12464 ++ return "iret";
12465 ++ default:
12466 ++ return "?";
12467 ++ }
12468 ++}
12469 ++
12470 ++static void print_reg(unsigned int reg, int offset)
12471 ++{
12472 ++ if (reg == ORC_REG_BP_INDIRECT)
12473 ++ printf("(bp%+d)", offset);
12474 ++ else if (reg == ORC_REG_SP_INDIRECT)
12475 ++ printf("(sp%+d)", offset);
12476 ++ else if (reg == ORC_REG_UNDEFINED)
12477 ++ printf("(und)");
12478 ++ else
12479 ++ printf("%s%+d", reg_name(reg), offset);
12480 ++}
12481 ++
12482 ++int orc_dump(const char *_objname)
12483 ++{
12484 ++ int fd, nr_entries, i, *orc_ip = NULL, orc_size = 0;
12485 ++ struct orc_entry *orc = NULL;
12486 ++ char *name;
12487 ++ size_t nr_sections;
12488 ++ Elf64_Addr orc_ip_addr = 0;
12489 ++ size_t shstrtab_idx;
12490 ++ Elf *elf;
12491 ++ Elf_Scn *scn;
12492 ++ GElf_Shdr sh;
12493 ++ GElf_Rela rela;
12494 ++ GElf_Sym sym;
12495 ++ Elf_Data *data, *symtab = NULL, *rela_orc_ip = NULL;
12496 ++
12497 ++
12498 ++ objname = _objname;
12499 ++
12500 ++ elf_version(EV_CURRENT);
12501 ++
12502 ++ fd = open(objname, O_RDONLY);
12503 ++ if (fd == -1) {
12504 ++ perror("open");
12505 ++ return -1;
12506 ++ }
12507 ++
12508 ++ elf = elf_begin(fd, ELF_C_READ_MMAP, NULL);
12509 ++ if (!elf) {
12510 ++ WARN_ELF("elf_begin");
12511 ++ return -1;
12512 ++ }
12513 ++
12514 ++ if (elf_getshdrnum(elf, &nr_sections)) {
12515 ++ WARN_ELF("elf_getshdrnum");
12516 ++ return -1;
12517 ++ }
12518 ++
12519 ++ if (elf_getshdrstrndx(elf, &shstrtab_idx)) {
12520 ++ WARN_ELF("elf_getshdrstrndx");
12521 ++ return -1;
12522 ++ }
12523 ++
12524 ++ for (i = 0; i < nr_sections; i++) {
12525 ++ scn = elf_getscn(elf, i);
12526 ++ if (!scn) {
12527 ++ WARN_ELF("elf_getscn");
12528 ++ return -1;
12529 ++ }
12530 ++
12531 ++ if (!gelf_getshdr(scn, &sh)) {
12532 ++ WARN_ELF("gelf_getshdr");
12533 ++ return -1;
12534 ++ }
12535 ++
12536 ++ name = elf_strptr(elf, shstrtab_idx, sh.sh_name);
12537 ++ if (!name) {
12538 ++ WARN_ELF("elf_strptr");
12539 ++ return -1;
12540 ++ }
12541 ++
12542 ++ data = elf_getdata(scn, NULL);
12543 ++ if (!data) {
12544 ++ WARN_ELF("elf_getdata");
12545 ++ return -1;
12546 ++ }
12547 ++
12548 ++ if (!strcmp(name, ".symtab")) {
12549 ++ symtab = data;
12550 ++ } else if (!strcmp(name, ".orc_unwind")) {
12551 ++ orc = data->d_buf;
12552 ++ orc_size = sh.sh_size;
12553 ++ } else if (!strcmp(name, ".orc_unwind_ip")) {
12554 ++ orc_ip = data->d_buf;
12555 ++ orc_ip_addr = sh.sh_addr;
12556 ++ } else if (!strcmp(name, ".rela.orc_unwind_ip")) {
12557 ++ rela_orc_ip = data;
12558 ++ }
12559 ++ }
12560 ++
12561 ++ if (!symtab || !orc || !orc_ip)
12562 ++ return 0;
12563 ++
12564 ++ if (orc_size % sizeof(*orc) != 0) {
12565 ++ WARN("bad .orc_unwind section size");
12566 ++ return -1;
12567 ++ }
12568 ++
12569 ++ nr_entries = orc_size / sizeof(*orc);
12570 ++ for (i = 0; i < nr_entries; i++) {
12571 ++ if (rela_orc_ip) {
12572 ++ if (!gelf_getrela(rela_orc_ip, i, &rela)) {
12573 ++ WARN_ELF("gelf_getrela");
12574 ++ return -1;
12575 ++ }
12576 ++
12577 ++ if (!gelf_getsym(symtab, GELF_R_SYM(rela.r_info), &sym)) {
12578 ++ WARN_ELF("gelf_getsym");
12579 ++ return -1;
12580 ++ }
12581 ++
12582 ++ scn = elf_getscn(elf, sym.st_shndx);
12583 ++ if (!scn) {
12584 ++ WARN_ELF("elf_getscn");
12585 ++ return -1;
12586 ++ }
12587 ++
12588 ++ if (!gelf_getshdr(scn, &sh)) {
12589 ++ WARN_ELF("gelf_getshdr");
12590 ++ return -1;
12591 ++ }
12592 ++
12593 ++ name = elf_strptr(elf, shstrtab_idx, sh.sh_name);
12594 ++ if (!name || !*name) {
12595 ++ WARN_ELF("elf_strptr");
12596 ++ return -1;
12597 ++ }
12598 ++
12599 ++ printf("%s+%llx:", name, (unsigned long long)rela.r_addend);
12600 ++
12601 ++ } else {
12602 ++ printf("%llx:", (unsigned long long)(orc_ip_addr + (i * sizeof(int)) + orc_ip[i]));
12603 ++ }
12604 ++
12605 ++
12606 ++ printf(" sp:");
12607 ++
12608 ++ print_reg(orc[i].sp_reg, orc[i].sp_offset);
12609 ++
12610 ++ printf(" bp:");
12611 ++
12612 ++ print_reg(orc[i].bp_reg, orc[i].bp_offset);
12613 ++
12614 ++ printf(" type:%s\n", orc_type_name(orc[i].type));
12615 ++ }
12616 ++
12617 ++ elf_end(elf);
12618 ++ close(fd);
12619 ++
12620 ++ return 0;
12621 ++}
12622 +diff --git a/tools/objtool/orc_gen.c b/tools/objtool/orc_gen.c
12623 +new file mode 100644
12624 +index 000000000000..18384d9be4e1
12625 +--- /dev/null
12626 ++++ b/tools/objtool/orc_gen.c
12627 +@@ -0,0 +1,221 @@
12628 ++/*
12629 ++ * Copyright (C) 2017 Josh Poimboeuf <jpoimboe@××××××.com>
12630 ++ *
12631 ++ * This program is free software; you can redistribute it and/or
12632 ++ * modify it under the terms of the GNU General Public License
12633 ++ * as published by the Free Software Foundation; either version 2
12634 ++ * of the License, or (at your option) any later version.
12635 ++ *
12636 ++ * This program is distributed in the hope that it will be useful,
12637 ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12638 ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12639 ++ * GNU General Public License for more details.
12640 ++ *
12641 ++ * You should have received a copy of the GNU General Public License
12642 ++ * along with this program; if not, see <http://www.gnu.org/licenses/>.
12643 ++ */
12644 ++
12645 ++#include <stdlib.h>
12646 ++#include <string.h>
12647 ++
12648 ++#include "orc.h"
12649 ++#include "check.h"
12650 ++#include "warn.h"
12651 ++
12652 ++int create_orc(struct objtool_file *file)
12653 ++{
12654 ++ struct instruction *insn;
12655 ++
12656 ++ for_each_insn(file, insn) {
12657 ++ struct orc_entry *orc = &insn->orc;
12658 ++ struct cfi_reg *cfa = &insn->state.cfa;
12659 ++ struct cfi_reg *bp = &insn->state.regs[CFI_BP];
12660 ++
12661 ++ if (cfa->base == CFI_UNDEFINED) {
12662 ++ orc->sp_reg = ORC_REG_UNDEFINED;
12663 ++ continue;
12664 ++ }
12665 ++
12666 ++ switch (cfa->base) {
12667 ++ case CFI_SP:
12668 ++ orc->sp_reg = ORC_REG_SP;
12669 ++ break;
12670 ++ case CFI_SP_INDIRECT:
12671 ++ orc->sp_reg = ORC_REG_SP_INDIRECT;
12672 ++ break;
12673 ++ case CFI_BP:
12674 ++ orc->sp_reg = ORC_REG_BP;
12675 ++ break;
12676 ++ case CFI_BP_INDIRECT:
12677 ++ orc->sp_reg = ORC_REG_BP_INDIRECT;
12678 ++ break;
12679 ++ case CFI_R10:
12680 ++ orc->sp_reg = ORC_REG_R10;
12681 ++ break;
12682 ++ case CFI_R13:
12683 ++ orc->sp_reg = ORC_REG_R13;
12684 ++ break;
12685 ++ case CFI_DI:
12686 ++ orc->sp_reg = ORC_REG_DI;
12687 ++ break;
12688 ++ case CFI_DX:
12689 ++ orc->sp_reg = ORC_REG_DX;
12690 ++ break;
12691 ++ default:
12692 ++ WARN_FUNC("unknown CFA base reg %d",
12693 ++ insn->sec, insn->offset, cfa->base);
12694 ++ return -1;
12695 ++ }
12696 ++
12697 ++ switch(bp->base) {
12698 ++ case CFI_UNDEFINED:
12699 ++ orc->bp_reg = ORC_REG_UNDEFINED;
12700 ++ break;
12701 ++ case CFI_CFA:
12702 ++ orc->bp_reg = ORC_REG_PREV_SP;
12703 ++ break;
12704 ++ case CFI_BP:
12705 ++ orc->bp_reg = ORC_REG_BP;
12706 ++ break;
12707 ++ default:
12708 ++ WARN_FUNC("unknown BP base reg %d",
12709 ++ insn->sec, insn->offset, bp->base);
12710 ++ return -1;
12711 ++ }
12712 ++
12713 ++ orc->sp_offset = cfa->offset;
12714 ++ orc->bp_offset = bp->offset;
12715 ++ orc->type = insn->state.type;
12716 ++ }
12717 ++
12718 ++ return 0;
12719 ++}
12720 ++
12721 ++static int create_orc_entry(struct section *u_sec, struct section *ip_relasec,
12722 ++ unsigned int idx, struct section *insn_sec,
12723 ++ unsigned long insn_off, struct orc_entry *o)
12724 ++{
12725 ++ struct orc_entry *orc;
12726 ++ struct rela *rela;
12727 ++
12728 ++ if (!insn_sec->sym) {
12729 ++ WARN("missing symbol for section %s", insn_sec->name);
12730 ++ return -1;
12731 ++ }
12732 ++
12733 ++ /* populate ORC data */
12734 ++ orc = (struct orc_entry *)u_sec->data->d_buf + idx;
12735 ++ memcpy(orc, o, sizeof(*orc));
12736 ++
12737 ++ /* populate rela for ip */
12738 ++ rela = malloc(sizeof(*rela));
12739 ++ if (!rela) {
12740 ++ perror("malloc");
12741 ++ return -1;
12742 ++ }
12743 ++ memset(rela, 0, sizeof(*rela));
12744 ++
12745 ++ rela->sym = insn_sec->sym;
12746 ++ rela->addend = insn_off;
12747 ++ rela->type = R_X86_64_PC32;
12748 ++ rela->offset = idx * sizeof(int);
12749 ++
12750 ++ list_add_tail(&rela->list, &ip_relasec->rela_list);
12751 ++ hash_add(ip_relasec->rela_hash, &rela->hash, rela->offset);
12752 ++
12753 ++ return 0;
12754 ++}
12755 ++
12756 ++int create_orc_sections(struct objtool_file *file)
12757 ++{
12758 ++ struct instruction *insn, *prev_insn;
12759 ++ struct section *sec, *u_sec, *ip_relasec;
12760 ++ unsigned int idx;
12761 ++
12762 ++ struct orc_entry empty = {
12763 ++ .sp_reg = ORC_REG_UNDEFINED,
12764 ++ .bp_reg = ORC_REG_UNDEFINED,
12765 ++ .type = ORC_TYPE_CALL,
12766 ++ };
12767 ++
12768 ++ sec = find_section_by_name(file->elf, ".orc_unwind");
12769 ++ if (sec) {
12770 ++ WARN("file already has .orc_unwind section, skipping");
12771 ++ return -1;
12772 ++ }
12773 ++
12774 ++ /* count the number of needed orcs */
12775 ++ idx = 0;
12776 ++ for_each_sec(file, sec) {
12777 ++ if (!sec->text)
12778 ++ continue;
12779 ++
12780 ++ prev_insn = NULL;
12781 ++ sec_for_each_insn(file, sec, insn) {
12782 ++ if (!prev_insn ||
12783 ++ memcmp(&insn->orc, &prev_insn->orc,
12784 ++ sizeof(struct orc_entry))) {
12785 ++ idx++;
12786 ++ }
12787 ++ prev_insn = insn;
12788 ++ }
12789 ++
12790 ++ /* section terminator */
12791 ++ if (prev_insn)
12792 ++ idx++;
12793 ++ }
12794 ++ if (!idx)
12795 ++ return -1;
12796 ++
12797 ++
12798 ++ /* create .orc_unwind_ip and .rela.orc_unwind_ip sections */
12799 ++ sec = elf_create_section(file->elf, ".orc_unwind_ip", sizeof(int), idx);
12800 ++ if (!sec)
12801 ++ return -1;
12802 ++
12803 ++ ip_relasec = elf_create_rela_section(file->elf, sec);
12804 ++ if (!ip_relasec)
12805 ++ return -1;
12806 ++
12807 ++ /* create .orc_unwind section */
12808 ++ u_sec = elf_create_section(file->elf, ".orc_unwind",
12809 ++ sizeof(struct orc_entry), idx);
12810 ++
12811 ++ /* populate sections */
12812 ++ idx = 0;
12813 ++ for_each_sec(file, sec) {
12814 ++ if (!sec->text)
12815 ++ continue;
12816 ++
12817 ++ prev_insn = NULL;
12818 ++ sec_for_each_insn(file, sec, insn) {
12819 ++ if (!prev_insn || memcmp(&insn->orc, &prev_insn->orc,
12820 ++ sizeof(struct orc_entry))) {
12821 ++
12822 ++ if (create_orc_entry(u_sec, ip_relasec, idx,
12823 ++ insn->sec, insn->offset,
12824 ++ &insn->orc))
12825 ++ return -1;
12826 ++
12827 ++ idx++;
12828 ++ }
12829 ++ prev_insn = insn;
12830 ++ }
12831 ++
12832 ++ /* section terminator */
12833 ++ if (prev_insn) {
12834 ++ if (create_orc_entry(u_sec, ip_relasec, idx,
12835 ++ prev_insn->sec,
12836 ++ prev_insn->offset + prev_insn->len,
12837 ++ &empty))
12838 ++ return -1;
12839 ++
12840 ++ idx++;
12841 ++ }
12842 ++ }
12843 ++
12844 ++ if (elf_rebuild_rela_section(ip_relasec))
12845 ++ return -1;
12846 ++
12847 ++ return 0;
12848 ++}
12849 +diff --git a/tools/objtool/special.c b/tools/objtool/special.c
12850 +index bff8abb3a4aa..84f001d52322 100644
12851 +--- a/tools/objtool/special.c
12852 ++++ b/tools/objtool/special.c
12853 +@@ -91,16 +91,16 @@ static int get_alt_entry(struct elf *elf, struct special_entry *entry,
12854 + alt->jump_or_nop = entry->jump_or_nop;
12855 +
12856 + if (alt->group) {
12857 +- alt->orig_len = *(unsigned char *)(sec->data + offset +
12858 ++ alt->orig_len = *(unsigned char *)(sec->data->d_buf + offset +
12859 + entry->orig_len);
12860 +- alt->new_len = *(unsigned char *)(sec->data + offset +
12861 ++ alt->new_len = *(unsigned char *)(sec->data->d_buf + offset +
12862 + entry->new_len);
12863 + }
12864 +
12865 + if (entry->feature) {
12866 + unsigned short feature;
12867 +
12868 +- feature = *(unsigned short *)(sec->data + offset +
12869 ++ feature = *(unsigned short *)(sec->data->d_buf + offset +
12870 + entry->feature);
12871 +
12872 + /*
12873 +diff --git a/tools/objtool/sync-check.sh b/tools/objtool/sync-check.sh
12874 +new file mode 100755
12875 +index 000000000000..1470e74e9d66
12876 +--- /dev/null
12877 ++++ b/tools/objtool/sync-check.sh
12878 +@@ -0,0 +1,29 @@
12879 ++#!/bin/sh
12880 ++# SPDX-License-Identifier: GPL-2.0
12881 ++
12882 ++FILES='
12883 ++arch/x86/lib/insn.c
12884 ++arch/x86/lib/inat.c
12885 ++arch/x86/lib/x86-opcode-map.txt
12886 ++arch/x86/tools/gen-insn-attr-x86.awk
12887 ++arch/x86/include/asm/insn.h
12888 ++arch/x86/include/asm/inat.h
12889 ++arch/x86/include/asm/inat_types.h
12890 ++arch/x86/include/asm/orc_types.h
12891 ++'
12892 ++
12893 ++check()
12894 ++{
12895 ++ local file=$1
12896 ++
12897 ++ diff $file ../../$file > /dev/null ||
12898 ++ echo "Warning: synced file at 'tools/objtool/$file' differs from latest kernel version at '$file'"
12899 ++}
12900 ++
12901 ++if [ ! -d ../../kernel ] || [ ! -d ../../tools ] || [ ! -d ../objtool ]; then
12902 ++ exit 0
12903 ++fi
12904 ++
12905 ++for i in $FILES; do
12906 ++ check $i
12907 ++done
12908 +diff --git a/tools/objtool/warn.h b/tools/objtool/warn.h
12909 +index ac7e07523e84..afd9f7a05f6d 100644
12910 +--- a/tools/objtool/warn.h
12911 ++++ b/tools/objtool/warn.h
12912 +@@ -18,6 +18,13 @@
12913 + #ifndef _WARN_H
12914 + #define _WARN_H
12915 +
12916 ++#include <stdlib.h>
12917 ++#include <string.h>
12918 ++#include <sys/types.h>
12919 ++#include <sys/stat.h>
12920 ++#include <fcntl.h>
12921 ++#include "elf.h"
12922 ++
12923 + extern const char *objname;
12924 +
12925 + static inline char *offstr(struct section *sec, unsigned long offset)
12926 +@@ -57,4 +64,7 @@ static inline char *offstr(struct section *sec, unsigned long offset)
12927 + free(_str); \
12928 + })
12929 +
12930 ++#define WARN_ELF(format, ...) \
12931 ++ WARN(format ": %s", ##__VA_ARGS__, elf_errmsg(-1))
12932 ++
12933 + #endif /* _WARN_H */
12934 +diff --git a/tools/perf/MANIFEST b/tools/perf/MANIFEST
12935 +index 0bda2cca2b3a..a4f98e131819 100644
12936 +--- a/tools/perf/MANIFEST
12937 ++++ b/tools/perf/MANIFEST
12938 +@@ -51,6 +51,7 @@ tools/include/asm-generic/bitops/arch_hweight.h
12939 + tools/include/asm-generic/bitops/atomic.h
12940 + tools/include/asm-generic/bitops/const_hweight.h
12941 + tools/include/asm-generic/bitops/__ffs.h
12942 ++tools/include/asm-generic/bitops/__ffz.h
12943 + tools/include/asm-generic/bitops/__fls.h
12944 + tools/include/asm-generic/bitops/find.h
12945 + tools/include/asm-generic/bitops/fls64.h
12946 +@@ -60,7 +61,9 @@ tools/include/asm-generic/bitops.h
12947 + tools/include/linux/atomic.h
12948 + tools/include/linux/bitops.h
12949 + tools/include/linux/compiler.h
12950 ++tools/include/linux/compiler-gcc.h
12951 + tools/include/linux/coresight-pmu.h
12952 ++tools/include/linux/bug.h
12953 + tools/include/linux/filter.h
12954 + tools/include/linux/hash.h
12955 + tools/include/linux/kernel.h
12956 +@@ -70,12 +73,15 @@ tools/include/uapi/asm-generic/mman-common.h
12957 + tools/include/uapi/asm-generic/mman.h
12958 + tools/include/uapi/linux/bpf.h
12959 + tools/include/uapi/linux/bpf_common.h
12960 ++tools/include/uapi/linux/fcntl.h
12961 + tools/include/uapi/linux/hw_breakpoint.h
12962 + tools/include/uapi/linux/mman.h
12963 + tools/include/uapi/linux/perf_event.h
12964 ++tools/include/uapi/linux/stat.h
12965 + tools/include/linux/poison.h
12966 + tools/include/linux/rbtree.h
12967 + tools/include/linux/rbtree_augmented.h
12968 ++tools/include/linux/refcount.h
12969 + tools/include/linux/string.h
12970 + tools/include/linux/stringify.h
12971 + tools/include/linux/types.h
12972 +diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
12973 +index 2b92ffef554b..ad3726c5754d 100644
12974 +--- a/tools/perf/Makefile.perf
12975 ++++ b/tools/perf/Makefile.perf
12976 +@@ -177,6 +177,36 @@ ifeq ($(filter-out $(NON_CONFIG_TARGETS),$(MAKECMDGOALS)),)
12977 + endif
12978 + endif
12979 +
12980 ++# The fixdep build - we force fixdep tool to be built as
12981 ++# the first target in the separate make session not to be
12982 ++# disturbed by any parallel make jobs. Once fixdep is done
12983 ++# we issue the requested build with FIXDEP=1 variable.
12984 ++#
12985 ++# The fixdep build is disabled for $(NON_CONFIG_TARGETS)
12986 ++# targets, because it's not necessary.
12987 ++
12988 ++ifdef FIXDEP
12989 ++ force_fixdep := 0
12990 ++else
12991 ++ force_fixdep := $(config)
12992 ++endif
12993 ++
12994 ++export srctree OUTPUT RM CC CXX LD AR CFLAGS CXXFLAGS V BISON FLEX AWK
12995 ++export HOSTCC HOSTLD HOSTAR
12996 ++
12997 ++include $(srctree)/tools/build/Makefile.include
12998 ++
12999 ++ifeq ($(force_fixdep),1)
13000 ++goals := $(filter-out all sub-make, $(MAKECMDGOALS))
13001 ++
13002 ++$(goals) all: sub-make
13003 ++
13004 ++sub-make: fixdep
13005 ++ @./check-headers.sh
13006 ++ $(Q)$(MAKE) FIXDEP=1 -f Makefile.perf $(goals)
13007 ++
13008 ++else # force_fixdep
13009 ++
13010 + # Set FEATURE_TESTS to 'all' so all possible feature checkers are executed.
13011 + # Without this setting the output feature dump file misses some features, for
13012 + # example, liberty. Select all checkers so we won't get an incomplete feature
13013 +@@ -348,10 +378,6 @@ strip: $(PROGRAMS) $(OUTPUT)perf
13014 +
13015 + PERF_IN := $(OUTPUT)perf-in.o
13016 +
13017 +-export srctree OUTPUT RM CC LD AR CFLAGS V BISON FLEX AWK
13018 +-export HOSTCC HOSTLD HOSTAR
13019 +-include $(srctree)/tools/build/Makefile.include
13020 +-
13021 + JEVENTS := $(OUTPUT)pmu-events/jevents
13022 + JEVENTS_IN := $(OUTPUT)pmu-events/jevents-in.o
13023 +
13024 +@@ -362,99 +388,6 @@ export JEVENTS
13025 + build := -f $(srctree)/tools/build/Makefile.build dir=. obj
13026 +
13027 + $(PERF_IN): prepare FORCE
13028 +- @(test -f ../../include/uapi/linux/perf_event.h && ( \
13029 +- (diff -B ../include/uapi/linux/perf_event.h ../../include/uapi/linux/perf_event.h >/dev/null) \
13030 +- || echo "Warning: tools/include/uapi/linux/perf_event.h differs from kernel" >&2 )) || true
13031 +- @(test -f ../../include/linux/hash.h && ( \
13032 +- (diff -B ../include/linux/hash.h ../../include/linux/hash.h >/dev/null) \
13033 +- || echo "Warning: tools/include/linux/hash.h differs from kernel" >&2 )) || true
13034 +- @(test -f ../../include/uapi/linux/hw_breakpoint.h && ( \
13035 +- (diff -B ../include/uapi/linux/hw_breakpoint.h ../../include/uapi/linux/hw_breakpoint.h >/dev/null) \
13036 +- || echo "Warning: tools/include/uapi/linux/hw_breakpoint.h differs from kernel" >&2 )) || true
13037 +- @(test -f ../../arch/x86/include/asm/disabled-features.h && ( \
13038 +- (diff -B ../arch/x86/include/asm/disabled-features.h ../../arch/x86/include/asm/disabled-features.h >/dev/null) \
13039 +- || echo "Warning: tools/arch/x86/include/asm/disabled-features.h differs from kernel" >&2 )) || true
13040 +- @(test -f ../../arch/x86/include/asm/required-features.h && ( \
13041 +- (diff -B ../arch/x86/include/asm/required-features.h ../../arch/x86/include/asm/required-features.h >/dev/null) \
13042 +- || echo "Warning: tools/arch/x86/include/asm/required-features.h differs from kernel" >&2 )) || true
13043 +- @(test -f ../../arch/x86/include/asm/cpufeatures.h && ( \
13044 +- (diff -B ../arch/x86/include/asm/cpufeatures.h ../../arch/x86/include/asm/cpufeatures.h >/dev/null) \
13045 +- || echo "Warning: tools/arch/x86/include/asm/cpufeatures.h differs from kernel" >&2 )) || true
13046 +- @(test -f ../../arch/x86/lib/memcpy_64.S && ( \
13047 +- (diff -B ../arch/x86/lib/memcpy_64.S ../../arch/x86/lib/memcpy_64.S >/dev/null) \
13048 +- || echo "Warning: tools/arch/x86/lib/memcpy_64.S differs from kernel" >&2 )) || true
13049 +- @(test -f ../../arch/x86/lib/memset_64.S && ( \
13050 +- (diff -B ../arch/x86/lib/memset_64.S ../../arch/x86/lib/memset_64.S >/dev/null) \
13051 +- || echo "Warning: tools/arch/x86/lib/memset_64.S differs from kernel" >&2 )) || true
13052 +- @(test -f ../../arch/arm/include/uapi/asm/perf_regs.h && ( \
13053 +- (diff -B ../arch/arm/include/uapi/asm/perf_regs.h ../../arch/arm/include/uapi/asm/perf_regs.h >/dev/null) \
13054 +- || echo "Warning: tools/arch/arm/include/uapi/asm/perf_regs.h differs from kernel" >&2 )) || true
13055 +- @(test -f ../../arch/arm64/include/uapi/asm/perf_regs.h && ( \
13056 +- (diff -B ../arch/arm64/include/uapi/asm/perf_regs.h ../../arch/arm64/include/uapi/asm/perf_regs.h >/dev/null) \
13057 +- || echo "Warning: tools/arch/arm64/include/uapi/asm/perf_regs.h differs from kernel" >&2 )) || true
13058 +- @(test -f ../../arch/powerpc/include/uapi/asm/perf_regs.h && ( \
13059 +- (diff -B ../arch/powerpc/include/uapi/asm/perf_regs.h ../../arch/powerpc/include/uapi/asm/perf_regs.h >/dev/null) \
13060 +- || echo "Warning: tools/arch/powerpc/include/uapi/asm/perf_regs.h differs from kernel" >&2 )) || true
13061 +- @(test -f ../../arch/x86/include/uapi/asm/perf_regs.h && ( \
13062 +- (diff -B ../arch/x86/include/uapi/asm/perf_regs.h ../../arch/x86/include/uapi/asm/perf_regs.h >/dev/null) \
13063 +- || echo "Warning: tools/arch/x86/include/uapi/asm/perf_regs.h differs from kernel" >&2 )) || true
13064 +- @(test -f ../../arch/x86/include/uapi/asm/kvm.h && ( \
13065 +- (diff -B ../arch/x86/include/uapi/asm/kvm.h ../../arch/x86/include/uapi/asm/kvm.h >/dev/null) \
13066 +- || echo "Warning: tools/arch/x86/include/uapi/asm/kvm.h differs from kernel" >&2 )) || true
13067 +- @(test -f ../../arch/x86/include/uapi/asm/kvm_perf.h && ( \
13068 +- (diff -B ../arch/x86/include/uapi/asm/kvm_perf.h ../../arch/x86/include/uapi/asm/kvm_perf.h >/dev/null) \
13069 +- || echo "Warning: tools/arch/x86/include/uapi/asm/kvm_perf.h differs from kernel" >&2 )) || true
13070 +- @(test -f ../../arch/x86/include/uapi/asm/svm.h && ( \
13071 +- (diff -B ../arch/x86/include/uapi/asm/svm.h ../../arch/x86/include/uapi/asm/svm.h >/dev/null) \
13072 +- || echo "Warning: tools/arch/x86/include/uapi/asm/svm.h differs from kernel" >&2 )) || true
13073 +- @(test -f ../../arch/x86/include/uapi/asm/vmx.h && ( \
13074 +- (diff -B ../arch/x86/include/uapi/asm/vmx.h ../../arch/x86/include/uapi/asm/vmx.h >/dev/null) \
13075 +- || echo "Warning: tools/arch/x86/include/uapi/asm/vmx.h differs from kernel" >&2 )) || true
13076 +- @(test -f ../../arch/powerpc/include/uapi/asm/kvm.h && ( \
13077 +- (diff -B ../arch/powerpc/include/uapi/asm/kvm.h ../../arch/powerpc/include/uapi/asm/kvm.h >/dev/null) \
13078 +- || echo "Warning: tools/arch/powerpc/include/uapi/asm/kvm.h differs from kernel" >&2 )) || true
13079 +- @(test -f ../../arch/s390/include/uapi/asm/kvm.h && ( \
13080 +- (diff -B ../arch/s390/include/uapi/asm/kvm.h ../../arch/s390/include/uapi/asm/kvm.h >/dev/null) \
13081 +- || echo "Warning: tools/arch/s390/include/uapi/asm/kvm.h differs from kernel" >&2 )) || true
13082 +- @(test -f ../../arch/s390/include/uapi/asm/kvm_perf.h && ( \
13083 +- (diff -B ../arch/s390/include/uapi/asm/kvm_perf.h ../../arch/s390/include/uapi/asm/kvm_perf.h >/dev/null) \
13084 +- || echo "Warning: tools/arch/s390/include/uapi/asm/kvm_perf.h differs from kernel" >&2 )) || true
13085 +- @(test -f ../../arch/s390/include/uapi/asm/sie.h && ( \
13086 +- (diff -B ../arch/s390/include/uapi/asm/sie.h ../../arch/s390/include/uapi/asm/sie.h >/dev/null) \
13087 +- || echo "Warning: tools/arch/s390/include/uapi/asm/sie.h differs from kernel" >&2 )) || true
13088 +- @(test -f ../../arch/arm/include/uapi/asm/kvm.h && ( \
13089 +- (diff -B ../arch/arm/include/uapi/asm/kvm.h ../../arch/arm/include/uapi/asm/kvm.h >/dev/null) \
13090 +- || echo "Warning: tools/arch/arm/include/uapi/asm/kvm.h differs from kernel" >&2 )) || true
13091 +- @(test -f ../../arch/arm64/include/uapi/asm/kvm.h && ( \
13092 +- (diff -B ../arch/arm64/include/uapi/asm/kvm.h ../../arch/arm64/include/uapi/asm/kvm.h >/dev/null) \
13093 +- || echo "Warning: tools/arch/arm64/include/uapi/asm/kvm.h differs from kernel" >&2 )) || true
13094 +- @(test -f ../../include/asm-generic/bitops/arch_hweight.h && ( \
13095 +- (diff -B ../include/asm-generic/bitops/arch_hweight.h ../../include/asm-generic/bitops/arch_hweight.h >/dev/null) \
13096 +- || echo "Warning: tools/include/asm-generic/bitops/arch_hweight.h differs from kernel" >&2 )) || true
13097 +- @(test -f ../../include/asm-generic/bitops/const_hweight.h && ( \
13098 +- (diff -B ../include/asm-generic/bitops/const_hweight.h ../../include/asm-generic/bitops/const_hweight.h >/dev/null) \
13099 +- || echo "Warning: tools/include/asm-generic/bitops/const_hweight.h differs from kernel" >&2 )) || true
13100 +- @(test -f ../../include/asm-generic/bitops/__fls.h && ( \
13101 +- (diff -B ../include/asm-generic/bitops/__fls.h ../../include/asm-generic/bitops/__fls.h >/dev/null) \
13102 +- || echo "Warning: tools/include/asm-generic/bitops/__fls.h differs from kernel" >&2 )) || true
13103 +- @(test -f ../../include/asm-generic/bitops/fls.h && ( \
13104 +- (diff -B ../include/asm-generic/bitops/fls.h ../../include/asm-generic/bitops/fls.h >/dev/null) \
13105 +- || echo "Warning: tools/include/asm-generic/bitops/fls.h differs from kernel" >&2 )) || true
13106 +- @(test -f ../../include/asm-generic/bitops/fls64.h && ( \
13107 +- (diff -B ../include/asm-generic/bitops/fls64.h ../../include/asm-generic/bitops/fls64.h >/dev/null) \
13108 +- || echo "Warning: tools/include/asm-generic/bitops/fls64.h differs from kernel" >&2 )) || true
13109 +- @(test -f ../../include/linux/coresight-pmu.h && ( \
13110 +- (diff -B ../include/linux/coresight-pmu.h ../../include/linux/coresight-pmu.h >/dev/null) \
13111 +- || echo "Warning: tools/include/linux/coresight-pmu.h differs from kernel" >&2 )) || true
13112 +- @(test -f ../../include/uapi/asm-generic/mman-common.h && ( \
13113 +- (diff -B ../include/uapi/asm-generic/mman-common.h ../../include/uapi/asm-generic/mman-common.h >/dev/null) \
13114 +- || echo "Warning: tools/include/uapi/asm-generic/mman-common.h differs from kernel" >&2 )) || true
13115 +- @(test -f ../../include/uapi/asm-generic/mman.h && ( \
13116 +- (diff -B -I "^#include <\(uapi/\)*asm-generic/mman-common.h>$$" ../include/uapi/asm-generic/mman.h ../../include/uapi/asm-generic/mman.h >/dev/null) \
13117 +- || echo "Warning: tools/include/uapi/asm-generic/mman.h differs from kernel" >&2 )) || true
13118 +- @(test -f ../../include/uapi/linux/mman.h && ( \
13119 +- (diff -B -I "^#include <\(uapi/\)*asm/mman.h>$$" ../include/uapi/linux/mman.h ../../include/uapi/linux/mman.h >/dev/null) \
13120 +- || echo "Warning: tools/include/uapi/linux/mman.h differs from kernel" >&2 )) || true
13121 + $(Q)$(MAKE) $(build)=perf
13122 +
13123 + $(JEVENTS_IN): FORCE
13124 +@@ -470,7 +403,7 @@ $(OUTPUT)perf: $(PERFLIBS) $(PERF_IN) $(PMU_EVENTS_IN) $(LIBTRACEEVENT_DYNAMIC_L
13125 + $(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) $(LIBTRACEEVENT_DYNAMIC_LIST_LDFLAGS) \
13126 + $(PERF_IN) $(PMU_EVENTS_IN) $(LIBS) -o $@
13127 +
13128 +-$(GTK_IN): fixdep FORCE
13129 ++$(GTK_IN): FORCE
13130 + $(Q)$(MAKE) $(build)=gtk
13131 +
13132 + $(OUTPUT)libperf-gtk.so: $(GTK_IN) $(PERFLIBS)
13133 +@@ -515,7 +448,7 @@ endif
13134 + __build-dir = $(subst $(OUTPUT),,$(dir $@))
13135 + build-dir = $(if $(__build-dir),$(__build-dir),.)
13136 +
13137 +-prepare: $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)common-cmds.h fixdep archheaders
13138 ++prepare: $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)common-cmds.h archheaders
13139 +
13140 + $(OUTPUT)%.o: %.c prepare FORCE
13141 + $(Q)$(MAKE) -f $(srctree)/tools/build/Makefile.build dir=$(build-dir) $@
13142 +@@ -555,7 +488,7 @@ $(patsubst perf-%,%.o,$(PROGRAMS)): $(wildcard */*.h)
13143 +
13144 + LIBPERF_IN := $(OUTPUT)libperf-in.o
13145 +
13146 +-$(LIBPERF_IN): prepare fixdep FORCE
13147 ++$(LIBPERF_IN): prepare FORCE
13148 + $(Q)$(MAKE) $(build)=libperf
13149 +
13150 + $(LIB_FILE): $(LIBPERF_IN)
13151 +@@ -563,10 +496,10 @@ $(LIB_FILE): $(LIBPERF_IN)
13152 +
13153 + LIBTRACEEVENT_FLAGS += plugin_dir=$(plugindir_SQ)
13154 +
13155 +-$(LIBTRACEEVENT): fixdep FORCE
13156 ++$(LIBTRACEEVENT): FORCE
13157 + $(Q)$(MAKE) -C $(TRACE_EVENT_DIR) $(LIBTRACEEVENT_FLAGS) O=$(OUTPUT) $(OUTPUT)libtraceevent.a
13158 +
13159 +-libtraceevent_plugins: fixdep FORCE
13160 ++libtraceevent_plugins: FORCE
13161 + $(Q)$(MAKE) -C $(TRACE_EVENT_DIR) $(LIBTRACEEVENT_FLAGS) O=$(OUTPUT) plugins
13162 +
13163 + $(LIBTRACEEVENT_DYNAMIC_LIST): libtraceevent_plugins
13164 +@@ -579,21 +512,21 @@ $(LIBTRACEEVENT)-clean:
13165 + install-traceevent-plugins: libtraceevent_plugins
13166 + $(Q)$(MAKE) -C $(TRACE_EVENT_DIR) $(LIBTRACEEVENT_FLAGS) O=$(OUTPUT) install_plugins
13167 +
13168 +-$(LIBAPI): fixdep FORCE
13169 ++$(LIBAPI): FORCE
13170 + $(Q)$(MAKE) -C $(LIB_DIR) O=$(OUTPUT) $(OUTPUT)libapi.a
13171 +
13172 + $(LIBAPI)-clean:
13173 + $(call QUIET_CLEAN, libapi)
13174 + $(Q)$(MAKE) -C $(LIB_DIR) O=$(OUTPUT) clean >/dev/null
13175 +
13176 +-$(LIBBPF): fixdep FORCE
13177 ++$(LIBBPF): FORCE
13178 + $(Q)$(MAKE) -C $(BPF_DIR) O=$(OUTPUT) $(OUTPUT)libbpf.a FEATURES_DUMP=$(FEATURE_DUMP_EXPORT)
13179 +
13180 + $(LIBBPF)-clean:
13181 + $(call QUIET_CLEAN, libbpf)
13182 + $(Q)$(MAKE) -C $(BPF_DIR) O=$(OUTPUT) clean >/dev/null
13183 +
13184 +-$(LIBSUBCMD): fixdep FORCE
13185 ++$(LIBSUBCMD): FORCE
13186 + $(Q)$(MAKE) -C $(SUBCMD_DIR) O=$(OUTPUT) $(OUTPUT)libsubcmd.a
13187 +
13188 + $(LIBSUBCMD)-clean:
13189 +@@ -790,3 +723,4 @@ FORCE:
13190 + .PHONY: $(GIT-HEAD-PHONY) TAGS tags cscope FORCE prepare
13191 + .PHONY: libtraceevent_plugins archheaders
13192 +
13193 ++endif # force_fixdep
13194 +diff --git a/tools/perf/arch/x86/entry/syscalls/syscall_64.tbl b/tools/perf/arch/x86/entry/syscalls/syscall_64.tbl
13195 +index 555263e385c9..e93ef0b38db8 100644
13196 +--- a/tools/perf/arch/x86/entry/syscalls/syscall_64.tbl
13197 ++++ b/tools/perf/arch/x86/entry/syscalls/syscall_64.tbl
13198 +@@ -335,6 +335,9 @@
13199 + 326 common copy_file_range sys_copy_file_range
13200 + 327 64 preadv2 sys_preadv2
13201 + 328 64 pwritev2 sys_pwritev2
13202 ++329 common pkey_mprotect sys_pkey_mprotect
13203 ++330 common pkey_alloc sys_pkey_alloc
13204 ++331 common pkey_free sys_pkey_free
13205 +
13206 + #
13207 + # x32-specific system call numbers start at 512 to avoid cache impact
13208 +@@ -374,5 +377,5 @@
13209 + 543 x32 io_setup compat_sys_io_setup
13210 + 544 x32 io_submit compat_sys_io_submit
13211 + 545 x32 execveat compat_sys_execveat/ptregs
13212 +-534 x32 preadv2 compat_sys_preadv2
13213 +-535 x32 pwritev2 compat_sys_pwritev2
13214 ++546 x32 preadv2 compat_sys_preadv64v2
13215 ++547 x32 pwritev2 compat_sys_pwritev64v2
13216 +diff --git a/tools/perf/check-headers.sh b/tools/perf/check-headers.sh
13217 +new file mode 100755
13218 +index 000000000000..83fe2202382e
13219 +--- /dev/null
13220 ++++ b/tools/perf/check-headers.sh
13221 +@@ -0,0 +1,61 @@
13222 ++#!/bin/sh
13223 ++
13224 ++HEADERS='
13225 ++include/uapi/linux/fcntl.h
13226 ++include/uapi/linux/perf_event.h
13227 ++include/uapi/linux/stat.h
13228 ++include/linux/hash.h
13229 ++include/uapi/linux/hw_breakpoint.h
13230 ++arch/x86/include/asm/disabled-features.h
13231 ++arch/x86/include/asm/required-features.h
13232 ++arch/x86/include/asm/cpufeatures.h
13233 ++arch/arm/include/uapi/asm/perf_regs.h
13234 ++arch/arm64/include/uapi/asm/perf_regs.h
13235 ++arch/powerpc/include/uapi/asm/perf_regs.h
13236 ++arch/x86/include/uapi/asm/perf_regs.h
13237 ++arch/x86/include/uapi/asm/kvm.h
13238 ++arch/x86/include/uapi/asm/kvm_perf.h
13239 ++arch/x86/include/uapi/asm/svm.h
13240 ++arch/x86/include/uapi/asm/vmx.h
13241 ++arch/powerpc/include/uapi/asm/kvm.h
13242 ++arch/s390/include/uapi/asm/kvm.h
13243 ++arch/s390/include/uapi/asm/kvm_perf.h
13244 ++arch/s390/include/uapi/asm/sie.h
13245 ++arch/arm/include/uapi/asm/kvm.h
13246 ++arch/arm64/include/uapi/asm/kvm.h
13247 ++include/asm-generic/bitops/arch_hweight.h
13248 ++include/asm-generic/bitops/const_hweight.h
13249 ++include/asm-generic/bitops/__fls.h
13250 ++include/asm-generic/bitops/fls.h
13251 ++include/asm-generic/bitops/fls64.h
13252 ++include/linux/coresight-pmu.h
13253 ++include/uapi/asm-generic/mman-common.h
13254 ++'
13255 ++
13256 ++check () {
13257 ++ file=$1
13258 ++ opts=
13259 ++
13260 ++ shift
13261 ++ while [ -n "$*" ]; do
13262 ++ opts="$opts \"$1\""
13263 ++ shift
13264 ++ done
13265 ++
13266 ++ cmd="diff $opts ../$file ../../$file > /dev/null"
13267 ++
13268 ++ test -f ../../$file &&
13269 ++ eval $cmd || echo "Warning: $file differs from kernel" >&2
13270 ++}
13271 ++
13272 ++
13273 ++# simple diff check
13274 ++for i in $HEADERS; do
13275 ++ check $i -B
13276 ++done
13277 ++
13278 ++# diff with extra ignore lines
13279 ++check arch/x86/lib/memcpy_64.S -B -I "^EXPORT_SYMBOL" -I "^#include <asm/export.h>"
13280 ++check arch/x86/lib/memset_64.S -B -I "^EXPORT_SYMBOL" -I "^#include <asm/export.h>"
13281 ++check include/uapi/asm-generic/mman.h -B -I "^#include <\(uapi/\)*asm-generic/mman-common.h>"
13282 ++check include/uapi/linux/mman.h -B -I "^#include <\(uapi/\)*asm/mman.h>"
13283 +diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h
13284 +index 43899e0d6fa1..e72d370889f8 100644
13285 +--- a/tools/perf/util/util.h
13286 ++++ b/tools/perf/util/util.h
13287 +@@ -23,8 +23,6 @@
13288 + #endif
13289 + #endif
13290 +
13291 +-#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
13292 +-
13293 + #ifdef __GNUC__
13294 + #define TYPEOF(x) (__typeof__(x))
13295 + #else