Magellan Linux

Contents of /trunk/kernel-alx/patches-4.9/0205-4.9.106-all-fixes.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3182 - (show annotations) (download)
Wed Aug 8 14:17:34 2018 UTC (5 years, 8 months ago) by niro
File size: 382694 byte(s)
-linux-4.9.106
1 diff --git a/Makefile b/Makefile
2 index 7d06dba3fde8..48d87e3a36c1 100644
3 --- a/Makefile
4 +++ b/Makefile
5 @@ -1,6 +1,6 @@
6 VERSION = 4
7 PATCHLEVEL = 9
8 -SUBLEVEL = 105
9 +SUBLEVEL = 106
10 EXTRAVERSION =
11 NAME = Roaring Lionus
12
13 diff --git a/arch/x86/crypto/Makefile b/arch/x86/crypto/Makefile
14 index 34b3fa2889d1..9e32d40d71bd 100644
15 --- a/arch/x86/crypto/Makefile
16 +++ b/arch/x86/crypto/Makefile
17 @@ -2,6 +2,8 @@
18 # Arch-specific CryptoAPI modules.
19 #
20
21 +OBJECT_FILES_NON_STANDARD := y
22 +
23 avx_supported := $(call as-instr,vpxor %xmm0$(comma)%xmm0$(comma)%xmm0,yes,no)
24 avx2_supported := $(call as-instr,vpgatherdd %ymm0$(comma)(%eax$(comma)%ymm1\
25 $(comma)4)$(comma)%ymm2,yes,no)
26 diff --git a/arch/x86/crypto/sha1-mb/Makefile b/arch/x86/crypto/sha1-mb/Makefile
27 index 2f8756375df5..2e14acc3da25 100644
28 --- a/arch/x86/crypto/sha1-mb/Makefile
29 +++ b/arch/x86/crypto/sha1-mb/Makefile
30 @@ -2,6 +2,8 @@
31 # Arch-specific CryptoAPI modules.
32 #
33
34 +OBJECT_FILES_NON_STANDARD := y
35 +
36 avx2_supported := $(call as-instr,vpgatherdd %ymm0$(comma)(%eax$(comma)%ymm1\
37 $(comma)4)$(comma)%ymm2,yes,no)
38 ifeq ($(avx2_supported),yes)
39 diff --git a/arch/x86/crypto/sha256-mb/Makefile b/arch/x86/crypto/sha256-mb/Makefile
40 index 41089e7c400c..45b4fca6c4a8 100644
41 --- a/arch/x86/crypto/sha256-mb/Makefile
42 +++ b/arch/x86/crypto/sha256-mb/Makefile
43 @@ -2,6 +2,8 @@
44 # Arch-specific CryptoAPI modules.
45 #
46
47 +OBJECT_FILES_NON_STANDARD := y
48 +
49 avx2_supported := $(call as-instr,vpgatherdd %ymm0$(comma)(%eax$(comma)%ymm1\
50 $(comma)4)$(comma)%ymm2,yes,no)
51 ifeq ($(avx2_supported),yes)
52 diff --git a/arch/x86/include/asm/orc_types.h b/arch/x86/include/asm/orc_types.h
53 new file mode 100644
54 index 000000000000..7dc777a6cb40
55 --- /dev/null
56 +++ b/arch/x86/include/asm/orc_types.h
57 @@ -0,0 +1,107 @@
58 +/*
59 + * Copyright (C) 2017 Josh Poimboeuf <jpoimboe@redhat.com>
60 + *
61 + * This program is free software; you can redistribute it and/or
62 + * modify it under the terms of the GNU General Public License
63 + * as published by the Free Software Foundation; either version 2
64 + * of the License, or (at your option) any later version.
65 + *
66 + * This program is distributed in the hope that it will be useful,
67 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
68 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
69 + * GNU General Public License for more details.
70 + *
71 + * You should have received a copy of the GNU General Public License
72 + * along with this program; if not, see <http://www.gnu.org/licenses/>.
73 + */
74 +
75 +#ifndef _ORC_TYPES_H
76 +#define _ORC_TYPES_H
77 +
78 +#include <linux/types.h>
79 +#include <linux/compiler.h>
80 +
81 +/*
82 + * The ORC_REG_* registers are base registers which are used to find other
83 + * registers on the stack.
84 + *
85 + * ORC_REG_PREV_SP, also known as DWARF Call Frame Address (CFA), is the
86 + * address of the previous frame: the caller's SP before it called the current
87 + * function.
88 + *
89 + * ORC_REG_UNDEFINED means the corresponding register's value didn't change in
90 + * the current frame.
91 + *
92 + * The most commonly used base registers are SP and BP -- which the previous SP
93 + * is usually based on -- and PREV_SP and UNDEFINED -- which the previous BP is
94 + * usually based on.
95 + *
96 + * The rest of the base registers are needed for special cases like entry code
97 + * and GCC realigned stacks.
98 + */
99 +#define ORC_REG_UNDEFINED 0
100 +#define ORC_REG_PREV_SP 1
101 +#define ORC_REG_DX 2
102 +#define ORC_REG_DI 3
103 +#define ORC_REG_BP 4
104 +#define ORC_REG_SP 5
105 +#define ORC_REG_R10 6
106 +#define ORC_REG_R13 7
107 +#define ORC_REG_BP_INDIRECT 8
108 +#define ORC_REG_SP_INDIRECT 9
109 +#define ORC_REG_MAX 15
110 +
111 +/*
112 + * ORC_TYPE_CALL: Indicates that sp_reg+sp_offset resolves to PREV_SP (the
113 + * caller's SP right before it made the call). Used for all callable
114 + * functions, i.e. all C code and all callable asm functions.
115 + *
116 + * ORC_TYPE_REGS: Used in entry code to indicate that sp_reg+sp_offset points
117 + * to a fully populated pt_regs from a syscall, interrupt, or exception.
118 + *
119 + * ORC_TYPE_REGS_IRET: Used in entry code to indicate that sp_reg+sp_offset
120 + * points to the iret return frame.
121 + *
122 + * The UNWIND_HINT macros are used only for the unwind_hint struct. They
123 + * aren't used in struct orc_entry due to size and complexity constraints.
124 + * Objtool converts them to real types when it converts the hints to orc
125 + * entries.
126 + */
127 +#define ORC_TYPE_CALL 0
128 +#define ORC_TYPE_REGS 1
129 +#define ORC_TYPE_REGS_IRET 2
130 +#define UNWIND_HINT_TYPE_SAVE 3
131 +#define UNWIND_HINT_TYPE_RESTORE 4
132 +
133 +#ifndef __ASSEMBLY__
134 +/*
135 + * This struct is more or less a vastly simplified version of the DWARF Call
136 + * Frame Information standard. It contains only the necessary parts of DWARF
137 + * CFI, simplified for ease of access by the in-kernel unwinder. It tells the
138 + * unwinder how to find the previous SP and BP (and sometimes entry regs) on
139 + * the stack for a given code address. Each instance of the struct corresponds
140 + * to one or more code locations.
141 + */
142 +struct orc_entry {
143 + s16 sp_offset;
144 + s16 bp_offset;
145 + unsigned sp_reg:4;
146 + unsigned bp_reg:4;
147 + unsigned type:2;
148 +};
149 +
150 +/*
151 + * This struct is used by asm and inline asm code to manually annotate the
152 + * location of registers on the stack for the ORC unwinder.
153 + *
154 + * Type can be either ORC_TYPE_* or UNWIND_HINT_TYPE_*.
155 + */
156 +struct unwind_hint {
157 + u32 ip;
158 + s16 sp_offset;
159 + u8 sp_reg;
160 + u8 type;
161 +};
162 +#endif /* __ASSEMBLY__ */
163 +
164 +#endif /* _ORC_TYPES_H */
165 diff --git a/arch/x86/include/asm/unwind_hints.h b/arch/x86/include/asm/unwind_hints.h
166 new file mode 100644
167 index 000000000000..5e02b11c9b86
168 --- /dev/null
169 +++ b/arch/x86/include/asm/unwind_hints.h
170 @@ -0,0 +1,103 @@
171 +#ifndef _ASM_X86_UNWIND_HINTS_H
172 +#define _ASM_X86_UNWIND_HINTS_H
173 +
174 +#include "orc_types.h"
175 +
176 +#ifdef __ASSEMBLY__
177 +
178 +/*
179 + * In asm, there are two kinds of code: normal C-type callable functions and
180 + * the rest. The normal callable functions can be called by other code, and
181 + * don't do anything unusual with the stack. Such normal callable functions
182 + * are annotated with the ENTRY/ENDPROC macros. Most asm code falls in this
183 + * category. In this case, no special debugging annotations are needed because
184 + * objtool can automatically generate the ORC data for the ORC unwinder to read
185 + * at runtime.
186 + *
187 + * Anything which doesn't fall into the above category, such as syscall and
188 + * interrupt handlers, tends to not be called directly by other functions, and
189 + * often does unusual non-C-function-type things with the stack pointer. Such
190 + * code needs to be annotated such that objtool can understand it. The
191 + * following CFI hint macros are for this type of code.
192 + *
193 + * These macros provide hints to objtool about the state of the stack at each
194 + * instruction. Objtool starts from the hints and follows the code flow,
195 + * making automatic CFI adjustments when it sees pushes and pops, filling out
196 + * the debuginfo as necessary. It will also warn if it sees any
197 + * inconsistencies.
198 + */
199 +.macro UNWIND_HINT sp_reg=ORC_REG_SP sp_offset=0 type=ORC_TYPE_CALL
200 +#ifdef CONFIG_STACK_VALIDATION
201 +.Lunwind_hint_ip_\@:
202 + .pushsection .discard.unwind_hints
203 + /* struct unwind_hint */
204 + .long .Lunwind_hint_ip_\@ - .
205 + .short \sp_offset
206 + .byte \sp_reg
207 + .byte \type
208 + .popsection
209 +#endif
210 +.endm
211 +
212 +.macro UNWIND_HINT_EMPTY
213 + UNWIND_HINT sp_reg=ORC_REG_UNDEFINED
214 +.endm
215 +
216 +.macro UNWIND_HINT_REGS base=%rsp offset=0 indirect=0 extra=1 iret=0
217 + .if \base == %rsp && \indirect
218 + .set sp_reg, ORC_REG_SP_INDIRECT
219 + .elseif \base == %rsp
220 + .set sp_reg, ORC_REG_SP
221 + .elseif \base == %rbp
222 + .set sp_reg, ORC_REG_BP
223 + .elseif \base == %rdi
224 + .set sp_reg, ORC_REG_DI
225 + .elseif \base == %rdx
226 + .set sp_reg, ORC_REG_DX
227 + .elseif \base == %r10
228 + .set sp_reg, ORC_REG_R10
229 + .else
230 + .error "UNWIND_HINT_REGS: bad base register"
231 + .endif
232 +
233 + .set sp_offset, \offset
234 +
235 + .if \iret
236 + .set type, ORC_TYPE_REGS_IRET
237 + .elseif \extra == 0
238 + .set type, ORC_TYPE_REGS_IRET
239 + .set sp_offset, \offset + (16*8)
240 + .else
241 + .set type, ORC_TYPE_REGS
242 + .endif
243 +
244 + UNWIND_HINT sp_reg=sp_reg sp_offset=sp_offset type=type
245 +.endm
246 +
247 +.macro UNWIND_HINT_IRET_REGS base=%rsp offset=0
248 + UNWIND_HINT_REGS base=\base offset=\offset iret=1
249 +.endm
250 +
251 +.macro UNWIND_HINT_FUNC sp_offset=8
252 + UNWIND_HINT sp_offset=\sp_offset
253 +.endm
254 +
255 +#else /* !__ASSEMBLY__ */
256 +
257 +#define UNWIND_HINT(sp_reg, sp_offset, type) \
258 + "987: \n\t" \
259 + ".pushsection .discard.unwind_hints\n\t" \
260 + /* struct unwind_hint */ \
261 + ".long 987b - .\n\t" \
262 + ".short " __stringify(sp_offset) "\n\t" \
263 + ".byte " __stringify(sp_reg) "\n\t" \
264 + ".byte " __stringify(type) "\n\t" \
265 + ".popsection\n\t"
266 +
267 +#define UNWIND_HINT_SAVE UNWIND_HINT(0, 0, UNWIND_HINT_TYPE_SAVE)
268 +
269 +#define UNWIND_HINT_RESTORE UNWIND_HINT(0, 0, UNWIND_HINT_TYPE_RESTORE)
270 +
271 +#endif /* __ASSEMBLY__ */
272 +
273 +#endif /* _ASM_X86_UNWIND_HINTS_H */
274 diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
275 index 79076d75bdbf..4c9c61517613 100644
276 --- a/arch/x86/kernel/Makefile
277 +++ b/arch/x86/kernel/Makefile
278 @@ -29,6 +29,7 @@ OBJECT_FILES_NON_STANDARD_head_$(BITS).o := y
279 OBJECT_FILES_NON_STANDARD_relocate_kernel_$(BITS).o := y
280 OBJECT_FILES_NON_STANDARD_mcount_$(BITS).o := y
281 OBJECT_FILES_NON_STANDARD_test_nx.o := y
282 +OBJECT_FILES_NON_STANDARD_paravirt_patch_$(BITS).o := y
283
284 # If instrumentation of this dir is enabled, boot hangs during first second.
285 # Probably could be more selective here, but note that files related to irqs,
286 diff --git a/arch/x86/kernel/acpi/Makefile b/arch/x86/kernel/acpi/Makefile
287 index 26b78d86f25a..85a9e17e0dbc 100644
288 --- a/arch/x86/kernel/acpi/Makefile
289 +++ b/arch/x86/kernel/acpi/Makefile
290 @@ -1,3 +1,5 @@
291 +OBJECT_FILES_NON_STANDARD_wakeup_$(BITS).o := y
292 +
293 obj-$(CONFIG_ACPI) += boot.o
294 obj-$(CONFIG_ACPI_SLEEP) += sleep.o wakeup_$(BITS).o
295 obj-$(CONFIG_ACPI_APEI) += apei.o
296 diff --git a/arch/x86/kernel/kprobes/opt.c b/arch/x86/kernel/kprobes/opt.c
297 index fa671b90c374..1808a9cc7701 100644
298 --- a/arch/x86/kernel/kprobes/opt.c
299 +++ b/arch/x86/kernel/kprobes/opt.c
300 @@ -28,6 +28,7 @@
301 #include <linux/kdebug.h>
302 #include <linux/kallsyms.h>
303 #include <linux/ftrace.h>
304 +#include <linux/frame.h>
305
306 #include <asm/text-patching.h>
307 #include <asm/cacheflush.h>
308 @@ -91,6 +92,7 @@ static void synthesize_set_arg1(kprobe_opcode_t *addr, unsigned long val)
309 }
310
311 asm (
312 + "optprobe_template_func:\n"
313 ".global optprobe_template_entry\n"
314 "optprobe_template_entry:\n"
315 #ifdef CONFIG_X86_64
316 @@ -128,7 +130,12 @@ asm (
317 " popf\n"
318 #endif
319 ".global optprobe_template_end\n"
320 - "optprobe_template_end:\n");
321 + "optprobe_template_end:\n"
322 + ".type optprobe_template_func, @function\n"
323 + ".size optprobe_template_func, .-optprobe_template_func\n");
324 +
325 +void optprobe_template_func(void);
326 +STACK_FRAME_NON_STANDARD(optprobe_template_func);
327
328 #define TMPL_MOVE_IDX \
329 ((long)&optprobe_template_val - (long)&optprobe_template_entry)
330 diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c
331 index 03f21dbfaa9d..4a12362a194a 100644
332 --- a/arch/x86/kernel/reboot.c
333 +++ b/arch/x86/kernel/reboot.c
334 @@ -9,6 +9,7 @@
335 #include <linux/sched.h>
336 #include <linux/tboot.h>
337 #include <linux/delay.h>
338 +#include <linux/frame.h>
339 #include <acpi/reboot.h>
340 #include <asm/io.h>
341 #include <asm/apic.h>
342 @@ -127,6 +128,7 @@ void __noreturn machine_real_restart(unsigned int type)
343 #ifdef CONFIG_APM_MODULE
344 EXPORT_SYMBOL(machine_real_restart);
345 #endif
346 +STACK_FRAME_NON_STANDARD(machine_real_restart);
347
348 /*
349 * Some Apple MacBook and MacBookPro's needs reboot=p to be able to reboot
350 diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S
351 index c7194e97c3d4..4ef267fb635a 100644
352 --- a/arch/x86/kernel/vmlinux.lds.S
353 +++ b/arch/x86/kernel/vmlinux.lds.S
354 @@ -353,6 +353,7 @@ SECTIONS
355 /DISCARD/ : {
356 *(.eh_frame)
357 *(__func_stack_frame_non_standard)
358 + *(__unreachable)
359 }
360 }
361
362 diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
363 index a27f9e442ffc..c4cd1280ac3e 100644
364 --- a/arch/x86/kvm/svm.c
365 +++ b/arch/x86/kvm/svm.c
366 @@ -36,6 +36,7 @@
367 #include <linux/slab.h>
368 #include <linux/amd-iommu.h>
369 #include <linux/hashtable.h>
370 +#include <linux/frame.h>
371
372 #include <asm/apic.h>
373 #include <asm/perf_event.h>
374 @@ -5111,6 +5112,7 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu)
375
376 mark_all_clean(svm->vmcb);
377 }
378 +STACK_FRAME_NON_STANDARD(svm_vcpu_run);
379
380 static void svm_set_cr3(struct kvm_vcpu *vcpu, unsigned long root)
381 {
382 diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
383 index 2827a9622d97..4a66a620fc17 100644
384 --- a/arch/x86/kvm/vmx.c
385 +++ b/arch/x86/kvm/vmx.c
386 @@ -33,6 +33,7 @@
387 #include <linux/slab.h>
388 #include <linux/tboot.h>
389 #include <linux/hrtimer.h>
390 +#include <linux/frame.h>
391 #include <linux/nospec.h>
392 #include "kvm_cache_regs.h"
393 #include "x86.h"
394 @@ -8698,6 +8699,7 @@ static void vmx_handle_external_intr(struct kvm_vcpu *vcpu)
395 );
396 }
397 }
398 +STACK_FRAME_NON_STANDARD(vmx_handle_external_intr);
399
400 static bool vmx_has_emulated_msr(int index)
401 {
402 @@ -9138,6 +9140,7 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu)
403 vmx_recover_nmi_blocking(vmx);
404 vmx_complete_interrupts(vmx);
405 }
406 +STACK_FRAME_NON_STANDARD(vmx_vcpu_run);
407
408 static void vmx_load_vmcs01(struct kvm_vcpu *vcpu)
409 {
410 diff --git a/arch/x86/lib/msr-reg.S b/arch/x86/lib/msr-reg.S
411 index c81556409bbb..10ffa7e8519f 100644
412 --- a/arch/x86/lib/msr-reg.S
413 +++ b/arch/x86/lib/msr-reg.S
414 @@ -13,14 +13,14 @@
415 .macro op_safe_regs op
416 ENTRY(\op\()_safe_regs)
417 pushq %rbx
418 - pushq %rbp
419 + pushq %r12
420 movq %rdi, %r10 /* Save pointer */
421 xorl %r11d, %r11d /* Return value */
422 movl (%rdi), %eax
423 movl 4(%rdi), %ecx
424 movl 8(%rdi), %edx
425 movl 12(%rdi), %ebx
426 - movl 20(%rdi), %ebp
427 + movl 20(%rdi), %r12d
428 movl 24(%rdi), %esi
429 movl 28(%rdi), %edi
430 1: \op
431 @@ -29,10 +29,10 @@ ENTRY(\op\()_safe_regs)
432 movl %ecx, 4(%r10)
433 movl %edx, 8(%r10)
434 movl %ebx, 12(%r10)
435 - movl %ebp, 20(%r10)
436 + movl %r12d, 20(%r10)
437 movl %esi, 24(%r10)
438 movl %edi, 28(%r10)
439 - popq %rbp
440 + popq %r12
441 popq %rbx
442 ret
443 3:
444 diff --git a/arch/x86/net/Makefile b/arch/x86/net/Makefile
445 index 90568c33ddb0..fefb4b619598 100644
446 --- a/arch/x86/net/Makefile
447 +++ b/arch/x86/net/Makefile
448 @@ -1,4 +1,6 @@
449 #
450 # Arch-specific network modules
451 #
452 +OBJECT_FILES_NON_STANDARD_bpf_jit.o += y
453 +
454 obj-$(CONFIG_BPF_JIT) += bpf_jit.o bpf_jit_comp.o
455 diff --git a/arch/x86/platform/efi/Makefile b/arch/x86/platform/efi/Makefile
456 index 066619b0700c..7a255022933e 100644
457 --- a/arch/x86/platform/efi/Makefile
458 +++ b/arch/x86/platform/efi/Makefile
459 @@ -1,4 +1,5 @@
460 OBJECT_FILES_NON_STANDARD_efi_thunk_$(BITS).o := y
461 +OBJECT_FILES_NON_STANDARD_efi_stub_$(BITS).o := y
462
463 obj-$(CONFIG_EFI) += quirks.o efi.o efi_$(BITS).o efi_stub_$(BITS).o
464 obj-$(CONFIG_ACPI_BGRT) += efi-bgrt.o
465 diff --git a/arch/x86/power/Makefile b/arch/x86/power/Makefile
466 index a6a198c33623..05041871ac90 100644
467 --- a/arch/x86/power/Makefile
468 +++ b/arch/x86/power/Makefile
469 @@ -1,3 +1,5 @@
470 +OBJECT_FILES_NON_STANDARD_hibernate_asm_$(BITS).o := y
471 +
472 # __restore_processor_state() restores %gs after S3 resume and so should not
473 # itself be stack-protected
474 nostackp := $(call cc-option, -fno-stack-protector)
475 diff --git a/arch/x86/xen/Makefile b/arch/x86/xen/Makefile
476 index e47e52787d32..4a54059f42ba 100644
477 --- a/arch/x86/xen/Makefile
478 +++ b/arch/x86/xen/Makefile
479 @@ -1,3 +1,6 @@
480 +OBJECT_FILES_NON_STANDARD_xen-asm_$(BITS).o := y
481 +OBJECT_FILES_NON_STANDARD_xen-pvh.o := y
482 +
483 ifdef CONFIG_FUNCTION_TRACER
484 # Do not profile debug and lowlevel utilities
485 CFLAGS_REMOVE_spinlock.o = -pg
486 diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
487 index 081437b5f381..e3a3f5a64884 100644
488 --- a/arch/x86/xen/enlighten.c
489 +++ b/arch/x86/xen/enlighten.c
490 @@ -75,6 +75,7 @@
491 #include <asm/mwait.h>
492 #include <asm/pci_x86.h>
493 #include <asm/cpu.h>
494 +#include <asm/unwind_hints.h>
495
496 #ifdef CONFIG_ACPI
497 #include <linux/acpi.h>
498 @@ -1452,10 +1453,12 @@ static void __ref xen_setup_gdt(int cpu)
499 * GDT. The new GDT has __KERNEL_CS with CS.L = 1
500 * and we are jumping to reload it.
501 */
502 - asm volatile ("pushq %0\n"
503 + asm volatile (UNWIND_HINT_SAVE
504 + "pushq %0\n"
505 "leaq 1f(%%rip),%0\n"
506 "pushq %0\n"
507 "lretq\n"
508 + UNWIND_HINT_RESTORE
509 "1:\n"
510 : "=&r" (dummy) : "0" (__KERNEL_CS));
511
512 diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h
513 index a1b1de17455c..2214b2f9c73c 100644
514 --- a/include/linux/compiler-gcc.h
515 +++ b/include/linux/compiler-gcc.h
516 @@ -203,6 +203,17 @@
517 #endif
518 #endif
519
520 +#ifdef CONFIG_STACK_VALIDATION
521 +#define annotate_unreachable() ({ \
522 + asm("1:\t\n" \
523 + ".pushsection __unreachable, \"a\"\t\n" \
524 + ".long 1b\t\n" \
525 + ".popsection\t\n"); \
526 +})
527 +#else
528 +#define annotate_unreachable()
529 +#endif
530 +
531 /*
532 * Mark a position in code as unreachable. This can be used to
533 * suppress control flow warnings after asm blocks that transfer
534 @@ -212,7 +223,8 @@
535 * this in the preprocessor, but we can live with this because they're
536 * unreleased. Really, we need to have autoconf for the kernel.
537 */
538 -#define unreachable() __builtin_unreachable()
539 +#define unreachable() \
540 + do { annotate_unreachable(); __builtin_unreachable(); } while (0)
541
542 /* Mark a function definition as prohibited from being cloned. */
543 #define __noclone __attribute__((__noclone__, __optimize__("no-tracer")))
544 diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c
545 index 561675589511..f5ab72ebda11 100644
546 --- a/kernel/kexec_core.c
547 +++ b/kernel/kexec_core.c
548 @@ -38,6 +38,7 @@
549 #include <linux/syscore_ops.h>
550 #include <linux/compiler.h>
551 #include <linux/hugetlb.h>
552 +#include <linux/frame.h>
553
554 #include <asm/page.h>
555 #include <asm/sections.h>
556 @@ -878,7 +879,7 @@ int kexec_load_disabled;
557 * only when panic_cpu holds the current CPU number; this is the only CPU
558 * which processes crash_kexec routines.
559 */
560 -void __crash_kexec(struct pt_regs *regs)
561 +void __noclone __crash_kexec(struct pt_regs *regs)
562 {
563 /* Take the kexec_mutex here to prevent sys_kexec_load
564 * running on one cpu from replacing the crash kernel
565 @@ -900,6 +901,7 @@ void __crash_kexec(struct pt_regs *regs)
566 mutex_unlock(&kexec_mutex);
567 }
568 }
569 +STACK_FRAME_NON_STANDARD(__crash_kexec);
570
571 void crash_kexec(struct pt_regs *regs)
572 {
573 diff --git a/tools/arch/arm/include/uapi/asm/kvm.h b/tools/arch/arm/include/uapi/asm/kvm.h
574 index a2b3eb313a25..0b8cf31d8416 100644
575 --- a/tools/arch/arm/include/uapi/asm/kvm.h
576 +++ b/tools/arch/arm/include/uapi/asm/kvm.h
577 @@ -84,6 +84,13 @@ struct kvm_regs {
578 #define KVM_VGIC_V2_DIST_SIZE 0x1000
579 #define KVM_VGIC_V2_CPU_SIZE 0x2000
580
581 +/* Supported VGICv3 address types */
582 +#define KVM_VGIC_V3_ADDR_TYPE_DIST 2
583 +#define KVM_VGIC_V3_ADDR_TYPE_REDIST 3
584 +
585 +#define KVM_VGIC_V3_DIST_SIZE SZ_64K
586 +#define KVM_VGIC_V3_REDIST_SIZE (2 * SZ_64K)
587 +
588 #define KVM_ARM_VCPU_POWER_OFF 0 /* CPU is started in OFF state */
589 #define KVM_ARM_VCPU_PSCI_0_2 1 /* CPU uses PSCI v0.2 */
590
591 @@ -166,6 +173,12 @@ struct kvm_arch_memory_slot {
592 #define KVM_REG_ARM_VFP_FPINST 0x1009
593 #define KVM_REG_ARM_VFP_FPINST2 0x100A
594
595 +/* KVM-as-firmware specific pseudo-registers */
596 +#define KVM_REG_ARM_FW (0x0014 << KVM_REG_ARM_COPROC_SHIFT)
597 +#define KVM_REG_ARM_FW_REG(r) (KVM_REG_ARM | KVM_REG_SIZE_U64 | \
598 + KVM_REG_ARM_FW | ((r) & 0xffff))
599 +#define KVM_REG_ARM_PSCI_VERSION KVM_REG_ARM_FW_REG(0)
600 +
601 /* Device Control API: ARM VGIC */
602 #define KVM_DEV_ARM_VGIC_GRP_ADDR 0
603 #define KVM_DEV_ARM_VGIC_GRP_DIST_REGS 1
604 diff --git a/tools/arch/arm64/include/uapi/asm/kvm.h b/tools/arch/arm64/include/uapi/asm/kvm.h
605 index 3051f86a9b5f..702de7a2b024 100644
606 --- a/tools/arch/arm64/include/uapi/asm/kvm.h
607 +++ b/tools/arch/arm64/include/uapi/asm/kvm.h
608 @@ -195,6 +195,12 @@ struct kvm_arch_memory_slot {
609 #define KVM_REG_ARM_TIMER_CNT ARM64_SYS_REG(3, 3, 14, 3, 2)
610 #define KVM_REG_ARM_TIMER_CVAL ARM64_SYS_REG(3, 3, 14, 0, 2)
611
612 +/* KVM-as-firmware specific pseudo-registers */
613 +#define KVM_REG_ARM_FW (0x0014 << KVM_REG_ARM_COPROC_SHIFT)
614 +#define KVM_REG_ARM_FW_REG(r) (KVM_REG_ARM64 | KVM_REG_SIZE_U64 | \
615 + KVM_REG_ARM_FW | ((r) & 0xffff))
616 +#define KVM_REG_ARM_PSCI_VERSION KVM_REG_ARM_FW_REG(0)
617 +
618 /* Device Control API: ARM VGIC */
619 #define KVM_DEV_ARM_VGIC_GRP_ADDR 0
620 #define KVM_DEV_ARM_VGIC_GRP_DIST_REGS 1
621 diff --git a/tools/arch/powerpc/include/uapi/asm/kvm.h b/tools/arch/powerpc/include/uapi/asm/kvm.h
622 index c93cf35ce379..0fb1326c3ea2 100644
623 --- a/tools/arch/powerpc/include/uapi/asm/kvm.h
624 +++ b/tools/arch/powerpc/include/uapi/asm/kvm.h
625 @@ -596,6 +596,7 @@ struct kvm_get_htab_header {
626 #define KVM_REG_PPC_TM_VSCR (KVM_REG_PPC_TM | KVM_REG_SIZE_U32 | 0x67)
627 #define KVM_REG_PPC_TM_DSCR (KVM_REG_PPC_TM | KVM_REG_SIZE_U64 | 0x68)
628 #define KVM_REG_PPC_TM_TAR (KVM_REG_PPC_TM | KVM_REG_SIZE_U64 | 0x69)
629 +#define KVM_REG_PPC_TM_XER (KVM_REG_PPC_TM | KVM_REG_SIZE_U64 | 0x6a)
630
631 /* PPC64 eXternal Interrupt Controller Specification */
632 #define KVM_DEV_XICS_GRP_SOURCES 1 /* 64-bit source attributes */
633 diff --git a/tools/arch/s390/include/uapi/asm/kvm.h b/tools/arch/s390/include/uapi/asm/kvm.h
634 index a2ffec4139ad..81c02e198527 100644
635 --- a/tools/arch/s390/include/uapi/asm/kvm.h
636 +++ b/tools/arch/s390/include/uapi/asm/kvm.h
637 @@ -197,6 +197,7 @@ struct kvm_guest_debug_arch {
638 #define KVM_SYNC_VRS (1UL << 6)
639 #define KVM_SYNC_RICCB (1UL << 7)
640 #define KVM_SYNC_FPRS (1UL << 8)
641 +#define KVM_SYNC_BPBC (1UL << 10)
642 /* definition of registers in kvm_run */
643 struct kvm_sync_regs {
644 __u64 prefix; /* prefix register */
645 @@ -217,7 +218,9 @@ struct kvm_sync_regs {
646 };
647 __u8 reserved[512]; /* for future vector expansion */
648 __u32 fpc; /* valid on KVM_SYNC_VRS or KVM_SYNC_FPRS */
649 - __u8 padding[52]; /* riccb needs to be 64byte aligned */
650 + __u8 bpbc : 1; /* bp mode */
651 + __u8 reserved2 : 7;
652 + __u8 padding1[51]; /* riccb needs to be 64byte aligned */
653 __u8 riccb[64]; /* runtime instrumentation controls block */
654 };
655
656 diff --git a/tools/arch/x86/include/asm/cpufeatures.h b/tools/arch/x86/include/asm/cpufeatures.h
657 index f79669a38c0c..c278f276c9b3 100644
658 --- a/tools/arch/x86/include/asm/cpufeatures.h
659 +++ b/tools/arch/x86/include/asm/cpufeatures.h
660 @@ -12,7 +12,7 @@
661 /*
662 * Defines x86 CPU feature bits
663 */
664 -#define NCAPINTS 18 /* N 32-bit words worth of info */
665 +#define NCAPINTS 19 /* N 32-bit words worth of info */
666 #define NBUGINTS 1 /* N 32-bit bug flags */
667
668 /*
669 @@ -189,17 +189,32 @@
670
671 #define X86_FEATURE_CPB ( 7*32+ 2) /* AMD Core Performance Boost */
672 #define X86_FEATURE_EPB ( 7*32+ 3) /* IA32_ENERGY_PERF_BIAS support */
673 +#define X86_FEATURE_INVPCID_SINGLE ( 7*32+ 4) /* Effectively INVPCID && CR4.PCIDE=1 */
674
675 #define X86_FEATURE_HW_PSTATE ( 7*32+ 8) /* AMD HW-PState */
676 #define X86_FEATURE_PROC_FEEDBACK ( 7*32+ 9) /* AMD ProcFeedbackInterface */
677
678 -#define X86_FEATURE_INTEL_PT ( 7*32+15) /* Intel Processor Trace */
679 -#define X86_FEATURE_AVX512_4VNNIW (7*32+16) /* AVX-512 Neural Network Instructions */
680 -#define X86_FEATURE_AVX512_4FMAPS (7*32+17) /* AVX-512 Multiply Accumulation Single precision */
681 +#define X86_FEATURE_RETPOLINE ( 7*32+12) /* "" Generic Retpoline mitigation for Spectre variant 2 */
682 +#define X86_FEATURE_RETPOLINE_AMD ( 7*32+13) /* "" AMD Retpoline mitigation for Spectre variant 2 */
683 +
684 +#define X86_FEATURE_MSR_SPEC_CTRL ( 7*32+16) /* "" MSR SPEC_CTRL is implemented */
685 +#define X86_FEATURE_SSBD ( 7*32+17) /* Speculative Store Bypass Disable */
686 +
687 +#define X86_FEATURE_RSB_CTXSW ( 7*32+19) /* "" Fill RSB on context switches */
688
689 /* Because the ALTERNATIVE scheme is for members of the X86_FEATURE club... */
690 #define X86_FEATURE_KAISER ( 7*32+31) /* CONFIG_PAGE_TABLE_ISOLATION w/o nokaiser */
691
692 +#define X86_FEATURE_USE_IBPB ( 7*32+21) /* "" Indirect Branch Prediction Barrier enabled */
693 +#define X86_FEATURE_USE_IBRS_FW ( 7*32+22) /* "" Use IBRS during runtime firmware calls */
694 +#define X86_FEATURE_SPEC_STORE_BYPASS_DISABLE ( 7*32+23) /* "" Disable Speculative Store Bypass. */
695 +#define X86_FEATURE_LS_CFG_SSBD ( 7*32+24) /* "" AMD SSBD implementation */
696 +#define X86_FEATURE_IBRS ( 7*32+25) /* Indirect Branch Restricted Speculation */
697 +#define X86_FEATURE_IBPB ( 7*32+26) /* Indirect Branch Prediction Barrier */
698 +#define X86_FEATURE_STIBP ( 7*32+27) /* Single Thread Indirect Branch Predictors */
699 +#define X86_FEATURE_ZEN ( 7*32+28) /* "" CPU is AMD family 0x17 (Zen) */
700 +
701 +
702 /* Virtualization flags: Linux defined, word 8 */
703 #define X86_FEATURE_TPR_SHADOW ( 8*32+ 0) /* Intel TPR Shadow */
704 #define X86_FEATURE_VNMI ( 8*32+ 1) /* Intel Virtual NMI */
705 @@ -231,6 +246,7 @@
706 #define X86_FEATURE_SMAP ( 9*32+20) /* Supervisor Mode Access Prevention */
707 #define X86_FEATURE_CLFLUSHOPT ( 9*32+23) /* CLFLUSHOPT instruction */
708 #define X86_FEATURE_CLWB ( 9*32+24) /* CLWB instruction */
709 +#define X86_FEATURE_INTEL_PT ( 9*32+25) /* Intel Processor Trace */
710 #define X86_FEATURE_AVX512PF ( 9*32+26) /* AVX-512 Prefetch */
711 #define X86_FEATURE_AVX512ER ( 9*32+27) /* AVX-512 Exponential and Reciprocal */
712 #define X86_FEATURE_AVX512CD ( 9*32+28) /* AVX-512 Conflict Detection */
713 @@ -255,6 +271,10 @@
714 /* AMD-defined CPU features, CPUID level 0x80000008 (ebx), word 13 */
715 #define X86_FEATURE_CLZERO (13*32+0) /* CLZERO instruction */
716 #define X86_FEATURE_IRPERF (13*32+1) /* Instructions Retired Count */
717 +#define X86_FEATURE_AMD_IBPB (13*32+12) /* Indirect Branch Prediction Barrier */
718 +#define X86_FEATURE_AMD_IBRS (13*32+14) /* Indirect Branch Restricted Speculation */
719 +#define X86_FEATURE_AMD_STIBP (13*32+15) /* Single Thread Indirect Branch Predictors */
720 +#define X86_FEATURE_VIRT_SSBD (13*32+25) /* Virtualized Speculative Store Bypass Disable */
721
722 /* Thermal and Power Management Leaf, CPUID level 0x00000006 (eax), word 14 */
723 #define X86_FEATURE_DTHERM (14*32+ 0) /* Digital Thermal Sensor */
724 @@ -290,6 +310,16 @@
725 #define X86_FEATURE_SUCCOR (17*32+1) /* Uncorrectable error containment and recovery */
726 #define X86_FEATURE_SMCA (17*32+3) /* Scalable MCA */
727
728 +
729 +/* Intel-defined CPU features, CPUID level 0x00000007:0 (EDX), word 18 */
730 +#define X86_FEATURE_AVX512_4VNNIW (18*32+ 2) /* AVX-512 Neural Network Instructions */
731 +#define X86_FEATURE_AVX512_4FMAPS (18*32+ 3) /* AVX-512 Multiply Accumulation Single precision */
732 +#define X86_FEATURE_PCONFIG (18*32+18) /* Intel PCONFIG */
733 +#define X86_FEATURE_SPEC_CTRL (18*32+26) /* "" Speculation Control (IBRS + IBPB) */
734 +#define X86_FEATURE_INTEL_STIBP (18*32+27) /* "" Single Thread Indirect Branch Predictors */
735 +#define X86_FEATURE_ARCH_CAPABILITIES (18*32+29) /* IA32_ARCH_CAPABILITIES MSR (Intel) */
736 +#define X86_FEATURE_SPEC_CTRL_SSBD (18*32+31) /* "" Speculative Store Bypass Disable */
737 +
738 /*
739 * BUG word(s)
740 */
741 @@ -314,4 +344,10 @@
742 #define X86_BUG_NULL_SEG X86_BUG(10) /* Nulling a selector preserves the base */
743 #define X86_BUG_SWAPGS_FENCE X86_BUG(11) /* SWAPGS without input dep on GS */
744 #define X86_BUG_MONITOR X86_BUG(12) /* IPI required to wake up remote CPU */
745 +#define X86_BUG_AMD_E400 X86_BUG(13) /* CPU is among the affected by Erratum 400 */
746 +#define X86_BUG_CPU_MELTDOWN X86_BUG(14) /* CPU is affected by meltdown attack and needs kernel page table isolation */
747 +#define X86_BUG_SPECTRE_V1 X86_BUG(15) /* CPU is affected by Spectre variant 1 attack with conditional branches */
748 +#define X86_BUG_SPECTRE_V2 X86_BUG(16) /* CPU is affected by Spectre variant 2 attack with indirect branches */
749 +#define X86_BUG_SPEC_STORE_BYPASS X86_BUG(17) /* CPU is affected by speculative store bypass attack */
750 +
751 #endif /* _ASM_X86_CPUFEATURES_H */
752 diff --git a/tools/arch/x86/include/asm/disabled-features.h b/tools/arch/x86/include/asm/disabled-features.h
753 index 85599ad4d024..1f8cca459c6c 100644
754 --- a/tools/arch/x86/include/asm/disabled-features.h
755 +++ b/tools/arch/x86/include/asm/disabled-features.h
756 @@ -21,11 +21,13 @@
757 # define DISABLE_K6_MTRR (1<<(X86_FEATURE_K6_MTRR & 31))
758 # define DISABLE_CYRIX_ARR (1<<(X86_FEATURE_CYRIX_ARR & 31))
759 # define DISABLE_CENTAUR_MCR (1<<(X86_FEATURE_CENTAUR_MCR & 31))
760 +# define DISABLE_PCID 0
761 #else
762 # define DISABLE_VME 0
763 # define DISABLE_K6_MTRR 0
764 # define DISABLE_CYRIX_ARR 0
765 # define DISABLE_CENTAUR_MCR 0
766 +# define DISABLE_PCID (1<<(X86_FEATURE_PCID & 31))
767 #endif /* CONFIG_X86_64 */
768
769 #ifdef CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS
770 @@ -43,7 +45,7 @@
771 #define DISABLED_MASK1 0
772 #define DISABLED_MASK2 0
773 #define DISABLED_MASK3 (DISABLE_CYRIX_ARR|DISABLE_CENTAUR_MCR|DISABLE_K6_MTRR)
774 -#define DISABLED_MASK4 0
775 +#define DISABLED_MASK4 (DISABLE_PCID)
776 #define DISABLED_MASK5 0
777 #define DISABLED_MASK6 0
778 #define DISABLED_MASK7 0
779 @@ -57,6 +59,7 @@
780 #define DISABLED_MASK15 0
781 #define DISABLED_MASK16 (DISABLE_PKU|DISABLE_OSPKE)
782 #define DISABLED_MASK17 0
783 -#define DISABLED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 18)
784 +#define DISABLED_MASK18 0
785 +#define DISABLED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 19)
786
787 #endif /* _ASM_X86_DISABLED_FEATURES_H */
788 diff --git a/tools/arch/x86/include/asm/required-features.h b/tools/arch/x86/include/asm/required-features.h
789 index fac9a5c0abe9..6847d85400a8 100644
790 --- a/tools/arch/x86/include/asm/required-features.h
791 +++ b/tools/arch/x86/include/asm/required-features.h
792 @@ -100,6 +100,7 @@
793 #define REQUIRED_MASK15 0
794 #define REQUIRED_MASK16 0
795 #define REQUIRED_MASK17 0
796 -#define REQUIRED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 18)
797 +#define REQUIRED_MASK18 0
798 +#define REQUIRED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 19)
799
800 #endif /* _ASM_X86_REQUIRED_FEATURES_H */
801 diff --git a/tools/include/asm-generic/bitops.h b/tools/include/asm-generic/bitops.h
802 index 653d1bad77de..0304600121da 100644
803 --- a/tools/include/asm-generic/bitops.h
804 +++ b/tools/include/asm-generic/bitops.h
805 @@ -13,6 +13,7 @@
806 */
807
808 #include <asm-generic/bitops/__ffs.h>
809 +#include <asm-generic/bitops/__ffz.h>
810 #include <asm-generic/bitops/fls.h>
811 #include <asm-generic/bitops/__fls.h>
812 #include <asm-generic/bitops/fls64.h>
813 diff --git a/tools/include/asm-generic/bitops/__ffz.h b/tools/include/asm-generic/bitops/__ffz.h
814 new file mode 100644
815 index 000000000000..6744bd4cdf46
816 --- /dev/null
817 +++ b/tools/include/asm-generic/bitops/__ffz.h
818 @@ -0,0 +1,12 @@
819 +#ifndef _ASM_GENERIC_BITOPS_FFZ_H_
820 +#define _ASM_GENERIC_BITOPS_FFZ_H_
821 +
822 +/*
823 + * ffz - find first zero in word.
824 + * @word: The word to search
825 + *
826 + * Undefined if no zero exists, so code should check against ~0UL first.
827 + */
828 +#define ffz(x) __ffs(~(x))
829 +
830 +#endif /* _ASM_GENERIC_BITOPS_FFZ_H_ */
831 diff --git a/tools/include/asm-generic/bitops/find.h b/tools/include/asm-generic/bitops/find.h
832 index 31f51547fcd4..5538ecdc964a 100644
833 --- a/tools/include/asm-generic/bitops/find.h
834 +++ b/tools/include/asm-generic/bitops/find.h
835 @@ -15,6 +15,21 @@ extern unsigned long find_next_bit(const unsigned long *addr, unsigned long
836 size, unsigned long offset);
837 #endif
838
839 +#ifndef find_next_zero_bit
840 +
841 +/**
842 + * find_next_zero_bit - find the next cleared bit in a memory region
843 + * @addr: The address to base the search on
844 + * @offset: The bitnumber to start searching at
845 + * @size: The bitmap size in bits
846 + *
847 + * Returns the bit number of the next zero bit
848 + * If no bits are zero, returns @size.
849 + */
850 +unsigned long find_next_zero_bit(const unsigned long *addr, unsigned long size,
851 + unsigned long offset);
852 +#endif
853 +
854 #ifndef find_first_bit
855
856 /**
857 @@ -30,4 +45,17 @@ extern unsigned long find_first_bit(const unsigned long *addr,
858
859 #endif /* find_first_bit */
860
861 +#ifndef find_first_zero_bit
862 +
863 +/**
864 + * find_first_zero_bit - find the first cleared bit in a memory region
865 + * @addr: The address to start the search at
866 + * @size: The maximum number of bits to search
867 + *
868 + * Returns the bit number of the first cleared bit.
869 + * If no bits are zero, returns @size.
870 + */
871 +unsigned long find_first_zero_bit(const unsigned long *addr, unsigned long size);
872 +#endif
873 +
874 #endif /*_TOOLS_LINUX_ASM_GENERIC_BITOPS_FIND_H_ */
875 diff --git a/tools/include/linux/atomic.h b/tools/include/linux/atomic.h
876 index 4e3d3d18ebab..9f21fc2b092b 100644
877 --- a/tools/include/linux/atomic.h
878 +++ b/tools/include/linux/atomic.h
879 @@ -3,4 +3,10 @@
880
881 #include <asm/atomic.h>
882
883 +/* atomic_cmpxchg_relaxed */
884 +#ifndef atomic_cmpxchg_relaxed
885 +#define atomic_cmpxchg_relaxed atomic_cmpxchg
886 +#define atomic_cmpxchg_release atomic_cmpxchg
887 +#endif /* atomic_cmpxchg_relaxed */
888 +
889 #endif /* __TOOLS_LINUX_ATOMIC_H */
890 diff --git a/tools/include/linux/bitmap.h b/tools/include/linux/bitmap.h
891 index 43c1c5021e4b..eef41d500e9e 100644
892 --- a/tools/include/linux/bitmap.h
893 +++ b/tools/include/linux/bitmap.h
894 @@ -35,6 +35,32 @@ static inline void bitmap_zero(unsigned long *dst, int nbits)
895 }
896 }
897
898 +static inline void bitmap_fill(unsigned long *dst, unsigned int nbits)
899 +{
900 + unsigned int nlongs = BITS_TO_LONGS(nbits);
901 + if (!small_const_nbits(nbits)) {
902 + unsigned int len = (nlongs - 1) * sizeof(unsigned long);
903 + memset(dst, 0xff, len);
904 + }
905 + dst[nlongs - 1] = BITMAP_LAST_WORD_MASK(nbits);
906 +}
907 +
908 +static inline int bitmap_empty(const unsigned long *src, unsigned nbits)
909 +{
910 + if (small_const_nbits(nbits))
911 + return ! (*src & BITMAP_LAST_WORD_MASK(nbits));
912 +
913 + return find_first_bit(src, nbits) == nbits;
914 +}
915 +
916 +static inline int bitmap_full(const unsigned long *src, unsigned int nbits)
917 +{
918 + if (small_const_nbits(nbits))
919 + return ! (~(*src) & BITMAP_LAST_WORD_MASK(nbits));
920 +
921 + return find_first_zero_bit(src, nbits) == nbits;
922 +}
923 +
924 static inline int bitmap_weight(const unsigned long *src, int nbits)
925 {
926 if (small_const_nbits(nbits))
927 diff --git a/tools/include/linux/bitops.h b/tools/include/linux/bitops.h
928 index 49c929a104ee..fc446343ff41 100644
929 --- a/tools/include/linux/bitops.h
930 +++ b/tools/include/linux/bitops.h
931 @@ -39,6 +39,11 @@ extern unsigned long __sw_hweight64(__u64 w);
932 (bit) < (size); \
933 (bit) = find_next_bit((addr), (size), (bit) + 1))
934
935 +#define for_each_clear_bit(bit, addr, size) \
936 + for ((bit) = find_first_zero_bit((addr), (size)); \
937 + (bit) < (size); \
938 + (bit) = find_next_zero_bit((addr), (size), (bit) + 1))
939 +
940 /* same as for_each_set_bit() but use bit as value to start with */
941 #define for_each_set_bit_from(bit, addr, size) \
942 for ((bit) = find_next_bit((addr), (size), (bit)); \
943 diff --git a/tools/include/linux/bug.h b/tools/include/linux/bug.h
944 new file mode 100644
945 index 000000000000..8e4a4f49135d
946 --- /dev/null
947 +++ b/tools/include/linux/bug.h
948 @@ -0,0 +1,10 @@
949 +#ifndef _TOOLS_PERF_LINUX_BUG_H
950 +#define _TOOLS_PERF_LINUX_BUG_H
951 +
952 +/* Force a compilation error if condition is true, but also produce a
953 + result (of value 0 and type size_t), so the expression can be used
954 + e.g. in a structure initializer (or where-ever else comma expressions
955 + aren't permitted). */
956 +#define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); }))
957 +
958 +#endif /* _TOOLS_PERF_LINUX_BUG_H */
959 diff --git a/tools/include/linux/compiler-gcc.h b/tools/include/linux/compiler-gcc.h
960 new file mode 100644
961 index 000000000000..825d44f89a29
962 --- /dev/null
963 +++ b/tools/include/linux/compiler-gcc.h
964 @@ -0,0 +1,21 @@
965 +#ifndef _TOOLS_LINUX_COMPILER_H_
966 +#error "Please don't include <linux/compiler-gcc.h> directly, include <linux/compiler.h> instead."
967 +#endif
968 +
969 +/*
970 + * Common definitions for all gcc versions go here.
971 + */
972 +#define GCC_VERSION (__GNUC__ * 10000 \
973 + + __GNUC_MINOR__ * 100 \
974 + + __GNUC_PATCHLEVEL__)
975 +
976 +#if GCC_VERSION >= 70000 && !defined(__CHECKER__)
977 +# define __fallthrough __attribute__ ((fallthrough))
978 +#endif
979 +
980 +#if GCC_VERSION >= 40300
981 +# define __compiletime_error(message) __attribute__((error(message)))
982 +#endif /* GCC_VERSION >= 40300 */
983 +
984 +/* &a[0] degrades to a pointer: a different type from an array */
985 +#define __must_be_array(a) BUILD_BUG_ON_ZERO(__same_type((a), &(a)[0]))
986 diff --git a/tools/include/linux/compiler.h b/tools/include/linux/compiler.h
987 index d94179f94caa..23299d7e7160 100644
988 --- a/tools/include/linux/compiler.h
989 +++ b/tools/include/linux/compiler.h
990 @@ -1,6 +1,14 @@
991 #ifndef _TOOLS_LINUX_COMPILER_H_
992 #define _TOOLS_LINUX_COMPILER_H_
993
994 +#ifdef __GNUC__
995 +#include <linux/compiler-gcc.h>
996 +#endif
997 +
998 +#ifndef __compiletime_error
999 +# define __compiletime_error(message)
1000 +#endif
1001 +
1002 /* Optimization barrier */
1003 /* The "volatile" is due to gcc bugs */
1004 #define barrier() __asm__ __volatile__("": : :"memory")
1005 @@ -9,6 +17,11 @@
1006 # define __always_inline inline __attribute__((always_inline))
1007 #endif
1008
1009 +/* Are two types/vars the same type (ignoring qualifiers)? */
1010 +#ifndef __same_type
1011 +# define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b))
1012 +#endif
1013 +
1014 #ifdef __ANDROID__
1015 /*
1016 * FIXME: Big hammer to get rid of tons of:
1017 @@ -21,6 +34,8 @@
1018 #endif
1019
1020 #define __user
1021 +#define __rcu
1022 +#define __read_mostly
1023
1024 #ifndef __attribute_const__
1025 # define __attribute_const__
1026 @@ -50,6 +65,8 @@
1027 # define unlikely(x) __builtin_expect(!!(x), 0)
1028 #endif
1029
1030 +#define uninitialized_var(x) x = *(&(x))
1031 +
1032 #define ACCESS_ONCE(x) (*(volatile typeof(x) *)&(x))
1033
1034 #include <linux/types.h>
1035 @@ -128,11 +145,7 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s
1036
1037
1038 #ifndef __fallthrough
1039 -# if defined(__GNUC__) && __GNUC__ >= 7
1040 -# define __fallthrough __attribute__ ((fallthrough))
1041 -# else
1042 -# define __fallthrough
1043 -# endif
1044 +# define __fallthrough
1045 #endif
1046
1047 #endif /* _TOOLS_LINUX_COMPILER_H */
1048 diff --git a/tools/include/linux/hashtable.h b/tools/include/linux/hashtable.h
1049 index c65cc0aa2659..251eabf2a05e 100644
1050 --- a/tools/include/linux/hashtable.h
1051 +++ b/tools/include/linux/hashtable.h
1052 @@ -13,10 +13,6 @@
1053 #include <linux/hash.h>
1054 #include <linux/log2.h>
1055
1056 -#ifndef ARRAY_SIZE
1057 -#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
1058 -#endif
1059 -
1060 #define DEFINE_HASHTABLE(name, bits) \
1061 struct hlist_head name[1 << (bits)] = \
1062 { [0 ... ((1 << (bits)) - 1)] = HLIST_HEAD_INIT }
1063 diff --git a/tools/include/linux/kernel.h b/tools/include/linux/kernel.h
1064 index 28607db02bd3..73ccc48126bb 100644
1065 --- a/tools/include/linux/kernel.h
1066 +++ b/tools/include/linux/kernel.h
1067 @@ -4,6 +4,11 @@
1068 #include <stdarg.h>
1069 #include <stddef.h>
1070 #include <assert.h>
1071 +#include <linux/compiler.h>
1072 +
1073 +#ifndef UINT_MAX
1074 +#define UINT_MAX (~0U)
1075 +#endif
1076
1077 #define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
1078
1079 @@ -72,6 +77,8 @@
1080 int vscnprintf(char *buf, size_t size, const char *fmt, va_list args);
1081 int scnprintf(char * buf, size_t size, const char * fmt, ...);
1082
1083 +#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) + __must_be_array(arr))
1084 +
1085 /*
1086 * This looks more complex than it should be. But we need to
1087 * get the type for the ~ right in round_down (it needs to be
1088 diff --git a/tools/include/linux/log2.h b/tools/include/linux/log2.h
1089 index d5677d39c1e4..0325cefc2220 100644
1090 --- a/tools/include/linux/log2.h
1091 +++ b/tools/include/linux/log2.h
1092 @@ -12,6 +12,9 @@
1093 #ifndef _TOOLS_LINUX_LOG2_H
1094 #define _TOOLS_LINUX_LOG2_H
1095
1096 +#include <linux/bitops.h>
1097 +#include <linux/types.h>
1098 +
1099 /*
1100 * non-constant log of base 2 calculators
1101 * - the arch may override these in asm/bitops.h if they can be implemented
1102 diff --git a/tools/include/linux/refcount.h b/tools/include/linux/refcount.h
1103 new file mode 100644
1104 index 000000000000..a0177c1f55b1
1105 --- /dev/null
1106 +++ b/tools/include/linux/refcount.h
1107 @@ -0,0 +1,151 @@
1108 +#ifndef _TOOLS_LINUX_REFCOUNT_H
1109 +#define _TOOLS_LINUX_REFCOUNT_H
1110 +
1111 +/*
1112 + * Variant of atomic_t specialized for reference counts.
1113 + *
1114 + * The interface matches the atomic_t interface (to aid in porting) but only
1115 + * provides the few functions one should use for reference counting.
1116 + *
1117 + * It differs in that the counter saturates at UINT_MAX and will not move once
1118 + * there. This avoids wrapping the counter and causing 'spurious'
1119 + * use-after-free issues.
1120 + *
1121 + * Memory ordering rules are slightly relaxed wrt regular atomic_t functions
1122 + * and provide only what is strictly required for refcounts.
1123 + *
1124 + * The increments are fully relaxed; these will not provide ordering. The
1125 + * rationale is that whatever is used to obtain the object we're increasing the
1126 + * reference count on will provide the ordering. For locked data structures,
1127 + * its the lock acquire, for RCU/lockless data structures its the dependent
1128 + * load.
1129 + *
1130 + * Do note that inc_not_zero() provides a control dependency which will order
1131 + * future stores against the inc, this ensures we'll never modify the object
1132 + * if we did not in fact acquire a reference.
1133 + *
1134 + * The decrements will provide release order, such that all the prior loads and
1135 + * stores will be issued before, it also provides a control dependency, which
1136 + * will order us against the subsequent free().
1137 + *
1138 + * The control dependency is against the load of the cmpxchg (ll/sc) that
1139 + * succeeded. This means the stores aren't fully ordered, but this is fine
1140 + * because the 1->0 transition indicates no concurrency.
1141 + *
1142 + * Note that the allocator is responsible for ordering things between free()
1143 + * and alloc().
1144 + *
1145 + */
1146 +
1147 +#include <linux/atomic.h>
1148 +#include <linux/kernel.h>
1149 +
1150 +#ifdef NDEBUG
1151 +#define REFCOUNT_WARN(cond, str) (void)(cond)
1152 +#define __refcount_check
1153 +#else
1154 +#define REFCOUNT_WARN(cond, str) BUG_ON(cond)
1155 +#define __refcount_check __must_check
1156 +#endif
1157 +
1158 +typedef struct refcount_struct {
1159 + atomic_t refs;
1160 +} refcount_t;
1161 +
1162 +#define REFCOUNT_INIT(n) { .refs = ATOMIC_INIT(n), }
1163 +
1164 +static inline void refcount_set(refcount_t *r, unsigned int n)
1165 +{
1166 + atomic_set(&r->refs, n);
1167 +}
1168 +
1169 +static inline unsigned int refcount_read(const refcount_t *r)
1170 +{
1171 + return atomic_read(&r->refs);
1172 +}
1173 +
1174 +/*
1175 + * Similar to atomic_inc_not_zero(), will saturate at UINT_MAX and WARN.
1176 + *
1177 + * Provides no memory ordering, it is assumed the caller has guaranteed the
1178 + * object memory to be stable (RCU, etc.). It does provide a control dependency
1179 + * and thereby orders future stores. See the comment on top.
1180 + */
1181 +static inline __refcount_check
1182 +bool refcount_inc_not_zero(refcount_t *r)
1183 +{
1184 + unsigned int old, new, val = atomic_read(&r->refs);
1185 +
1186 + for (;;) {
1187 + new = val + 1;
1188 +
1189 + if (!val)
1190 + return false;
1191 +
1192 + if (unlikely(!new))
1193 + return true;
1194 +
1195 + old = atomic_cmpxchg_relaxed(&r->refs, val, new);
1196 + if (old == val)
1197 + break;
1198 +
1199 + val = old;
1200 + }
1201 +
1202 + REFCOUNT_WARN(new == UINT_MAX, "refcount_t: saturated; leaking memory.\n");
1203 +
1204 + return true;
1205 +}
1206 +
1207 +/*
1208 + * Similar to atomic_inc(), will saturate at UINT_MAX and WARN.
1209 + *
1210 + * Provides no memory ordering, it is assumed the caller already has a
1211 + * reference on the object, will WARN when this is not so.
1212 + */
1213 +static inline void refcount_inc(refcount_t *r)
1214 +{
1215 + REFCOUNT_WARN(!refcount_inc_not_zero(r), "refcount_t: increment on 0; use-after-free.\n");
1216 +}
1217 +
1218 +/*
1219 + * Similar to atomic_dec_and_test(), it will WARN on underflow and fail to
1220 + * decrement when saturated at UINT_MAX.
1221 + *
1222 + * Provides release memory ordering, such that prior loads and stores are done
1223 + * before, and provides a control dependency such that free() must come after.
1224 + * See the comment on top.
1225 + */
1226 +static inline __refcount_check
1227 +bool refcount_sub_and_test(unsigned int i, refcount_t *r)
1228 +{
1229 + unsigned int old, new, val = atomic_read(&r->refs);
1230 +
1231 + for (;;) {
1232 + if (unlikely(val == UINT_MAX))
1233 + return false;
1234 +
1235 + new = val - i;
1236 + if (new > val) {
1237 + REFCOUNT_WARN(new > val, "refcount_t: underflow; use-after-free.\n");
1238 + return false;
1239 + }
1240 +
1241 + old = atomic_cmpxchg_release(&r->refs, val, new);
1242 + if (old == val)
1243 + break;
1244 +
1245 + val = old;
1246 + }
1247 +
1248 + return !new;
1249 +}
1250 +
1251 +static inline __refcount_check
1252 +bool refcount_dec_and_test(refcount_t *r)
1253 +{
1254 + return refcount_sub_and_test(1, r);
1255 +}
1256 +
1257 +
1258 +#endif /* _ATOMIC_LINUX_REFCOUNT_H */
1259 diff --git a/tools/include/linux/spinlock.h b/tools/include/linux/spinlock.h
1260 new file mode 100644
1261 index 000000000000..58397dcb19d6
1262 --- /dev/null
1263 +++ b/tools/include/linux/spinlock.h
1264 @@ -0,0 +1,5 @@
1265 +#define spinlock_t pthread_mutex_t
1266 +#define DEFINE_SPINLOCK(x) pthread_mutex_t x = PTHREAD_MUTEX_INITIALIZER;
1267 +
1268 +#define spin_lock_irqsave(x, f) (void)f, pthread_mutex_lock(x)
1269 +#define spin_unlock_irqrestore(x, f) (void)f, pthread_mutex_unlock(x)
1270 diff --git a/tools/include/linux/types.h b/tools/include/linux/types.h
1271 index 8ebf6278b2ef..77a28a26a670 100644
1272 --- a/tools/include/linux/types.h
1273 +++ b/tools/include/linux/types.h
1274 @@ -7,6 +7,7 @@
1275
1276 #define __SANE_USERSPACE_TYPES__ /* For PPC64, to get LL64 types */
1277 #include <asm/types.h>
1278 +#include <asm/posix_types.h>
1279
1280 struct page;
1281 struct kmem_cache;
1282 @@ -42,11 +43,7 @@ typedef __s8 s8;
1283 #else
1284 #define __bitwise__
1285 #endif
1286 -#ifdef __CHECK_ENDIAN__
1287 #define __bitwise __bitwise__
1288 -#else
1289 -#define __bitwise
1290 -#endif
1291
1292 #define __force
1293 #define __user
1294 diff --git a/tools/include/uapi/asm-generic/mman-common.h b/tools/include/uapi/asm-generic/mman-common.h
1295 index 58274382a616..8c27db0c5c08 100644
1296 --- a/tools/include/uapi/asm-generic/mman-common.h
1297 +++ b/tools/include/uapi/asm-generic/mman-common.h
1298 @@ -72,4 +72,9 @@
1299 #define MAP_HUGE_SHIFT 26
1300 #define MAP_HUGE_MASK 0x3f
1301
1302 +#define PKEY_DISABLE_ACCESS 0x1
1303 +#define PKEY_DISABLE_WRITE 0x2
1304 +#define PKEY_ACCESS_MASK (PKEY_DISABLE_ACCESS |\
1305 + PKEY_DISABLE_WRITE)
1306 +
1307 #endif /* __ASM_GENERIC_MMAN_COMMON_H */
1308 diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h
1309 index 9e5fc168c8a3..f09c70b97eca 100644
1310 --- a/tools/include/uapi/linux/bpf.h
1311 +++ b/tools/include/uapi/linux/bpf.h
1312 @@ -95,6 +95,7 @@ enum bpf_prog_type {
1313 BPF_PROG_TYPE_SCHED_ACT,
1314 BPF_PROG_TYPE_TRACEPOINT,
1315 BPF_PROG_TYPE_XDP,
1316 + BPF_PROG_TYPE_PERF_EVENT,
1317 };
1318
1319 #define BPF_PSEUDO_MAP_FD 1
1320 @@ -375,6 +376,56 @@ enum bpf_func_id {
1321 */
1322 BPF_FUNC_probe_write_user,
1323
1324 + /**
1325 + * bpf_current_task_under_cgroup(map, index) - Check cgroup2 membership of current task
1326 + * @map: pointer to bpf_map in BPF_MAP_TYPE_CGROUP_ARRAY type
1327 + * @index: index of the cgroup in the bpf_map
1328 + * Return:
1329 + * == 0 current failed the cgroup2 descendant test
1330 + * == 1 current succeeded the cgroup2 descendant test
1331 + * < 0 error
1332 + */
1333 + BPF_FUNC_current_task_under_cgroup,
1334 +
1335 + /**
1336 + * bpf_skb_change_tail(skb, len, flags)
1337 + * The helper will resize the skb to the given new size,
1338 + * to be used f.e. with control messages.
1339 + * @skb: pointer to skb
1340 + * @len: new skb length
1341 + * @flags: reserved
1342 + * Return: 0 on success or negative error
1343 + */
1344 + BPF_FUNC_skb_change_tail,
1345 +
1346 + /**
1347 + * bpf_skb_pull_data(skb, len)
1348 + * The helper will pull in non-linear data in case the
1349 + * skb is non-linear and not all of len are part of the
1350 + * linear section. Only needed for read/write with direct
1351 + * packet access.
1352 + * @skb: pointer to skb
1353 + * @len: len to make read/writeable
1354 + * Return: 0 on success or negative error
1355 + */
1356 + BPF_FUNC_skb_pull_data,
1357 +
1358 + /**
1359 + * bpf_csum_update(skb, csum)
1360 + * Adds csum into skb->csum in case of CHECKSUM_COMPLETE.
1361 + * @skb: pointer to skb
1362 + * @csum: csum to add
1363 + * Return: csum on success or negative error
1364 + */
1365 + BPF_FUNC_csum_update,
1366 +
1367 + /**
1368 + * bpf_set_hash_invalid(skb)
1369 + * Invalidate current skb>hash.
1370 + * @skb: pointer to skb
1371 + */
1372 + BPF_FUNC_set_hash_invalid,
1373 +
1374 __BPF_FUNC_MAX_ID,
1375 };
1376
1377 diff --git a/tools/include/uapi/linux/fcntl.h b/tools/include/uapi/linux/fcntl.h
1378 new file mode 100644
1379 index 000000000000..beed138bd359
1380 --- /dev/null
1381 +++ b/tools/include/uapi/linux/fcntl.h
1382 @@ -0,0 +1,67 @@
1383 +#ifndef _UAPI_LINUX_FCNTL_H
1384 +#define _UAPI_LINUX_FCNTL_H
1385 +
1386 +#include <asm/fcntl.h>
1387 +
1388 +#define F_SETLEASE (F_LINUX_SPECIFIC_BASE + 0)
1389 +#define F_GETLEASE (F_LINUX_SPECIFIC_BASE + 1)
1390 +
1391 +/*
1392 + * Cancel a blocking posix lock; internal use only until we expose an
1393 + * asynchronous lock api to userspace:
1394 + */
1395 +#define F_CANCELLK (F_LINUX_SPECIFIC_BASE + 5)
1396 +
1397 +/* Create a file descriptor with FD_CLOEXEC set. */
1398 +#define F_DUPFD_CLOEXEC (F_LINUX_SPECIFIC_BASE + 6)
1399 +
1400 +/*
1401 + * Request nofications on a directory.
1402 + * See below for events that may be notified.
1403 + */
1404 +#define F_NOTIFY (F_LINUX_SPECIFIC_BASE+2)
1405 +
1406 +/*
1407 + * Set and get of pipe page size array
1408 + */
1409 +#define F_SETPIPE_SZ (F_LINUX_SPECIFIC_BASE + 7)
1410 +#define F_GETPIPE_SZ (F_LINUX_SPECIFIC_BASE + 8)
1411 +
1412 +/*
1413 + * Set/Get seals
1414 + */
1415 +#define F_ADD_SEALS (F_LINUX_SPECIFIC_BASE + 9)
1416 +#define F_GET_SEALS (F_LINUX_SPECIFIC_BASE + 10)
1417 +
1418 +/*
1419 + * Types of seals
1420 + */
1421 +#define F_SEAL_SEAL 0x0001 /* prevent further seals from being set */
1422 +#define F_SEAL_SHRINK 0x0002 /* prevent file from shrinking */
1423 +#define F_SEAL_GROW 0x0004 /* prevent file from growing */
1424 +#define F_SEAL_WRITE 0x0008 /* prevent writes */
1425 +/* (1U << 31) is reserved for signed error codes */
1426 +
1427 +/*
1428 + * Types of directory notifications that may be requested.
1429 + */
1430 +#define DN_ACCESS 0x00000001 /* File accessed */
1431 +#define DN_MODIFY 0x00000002 /* File modified */
1432 +#define DN_CREATE 0x00000004 /* File created */
1433 +#define DN_DELETE 0x00000008 /* File removed */
1434 +#define DN_RENAME 0x00000010 /* File renamed */
1435 +#define DN_ATTRIB 0x00000020 /* File changed attibutes */
1436 +#define DN_MULTISHOT 0x80000000 /* Don't remove notifier */
1437 +
1438 +#define AT_FDCWD -100 /* Special value used to indicate
1439 + openat should use the current
1440 + working directory. */
1441 +#define AT_SYMLINK_NOFOLLOW 0x100 /* Do not follow symbolic links. */
1442 +#define AT_REMOVEDIR 0x200 /* Remove directory instead of
1443 + unlinking file. */
1444 +#define AT_SYMLINK_FOLLOW 0x400 /* Follow symbolic links. */
1445 +#define AT_NO_AUTOMOUNT 0x800 /* Suppress terminal automount traversal */
1446 +#define AT_EMPTY_PATH 0x1000 /* Allow empty relative pathname */
1447 +
1448 +
1449 +#endif /* _UAPI_LINUX_FCNTL_H */
1450 diff --git a/tools/include/uapi/linux/stat.h b/tools/include/uapi/linux/stat.h
1451 new file mode 100644
1452 index 000000000000..7fec7e36d921
1453 --- /dev/null
1454 +++ b/tools/include/uapi/linux/stat.h
1455 @@ -0,0 +1,45 @@
1456 +#ifndef _UAPI_LINUX_STAT_H
1457 +#define _UAPI_LINUX_STAT_H
1458 +
1459 +
1460 +#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2)
1461 +
1462 +#define S_IFMT 00170000
1463 +#define S_IFSOCK 0140000
1464 +#define S_IFLNK 0120000
1465 +#define S_IFREG 0100000
1466 +#define S_IFBLK 0060000
1467 +#define S_IFDIR 0040000
1468 +#define S_IFCHR 0020000
1469 +#define S_IFIFO 0010000
1470 +#define S_ISUID 0004000
1471 +#define S_ISGID 0002000
1472 +#define S_ISVTX 0001000
1473 +
1474 +#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
1475 +#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
1476 +#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
1477 +#define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
1478 +#define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
1479 +#define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
1480 +#define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)
1481 +
1482 +#define S_IRWXU 00700
1483 +#define S_IRUSR 00400
1484 +#define S_IWUSR 00200
1485 +#define S_IXUSR 00100
1486 +
1487 +#define S_IRWXG 00070
1488 +#define S_IRGRP 00040
1489 +#define S_IWGRP 00020
1490 +#define S_IXGRP 00010
1491 +
1492 +#define S_IRWXO 00007
1493 +#define S_IROTH 00004
1494 +#define S_IWOTH 00002
1495 +#define S_IXOTH 00001
1496 +
1497 +#endif
1498 +
1499 +
1500 +#endif /* _UAPI_LINUX_STAT_H */
1501 diff --git a/tools/lib/find_bit.c b/tools/lib/find_bit.c
1502 index 9122a9e80046..6d8b8f22cf55 100644
1503 --- a/tools/lib/find_bit.c
1504 +++ b/tools/lib/find_bit.c
1505 @@ -82,3 +82,28 @@ unsigned long find_first_bit(const unsigned long *addr, unsigned long size)
1506 return size;
1507 }
1508 #endif
1509 +
1510 +#ifndef find_first_zero_bit
1511 +/*
1512 + * Find the first cleared bit in a memory region.
1513 + */
1514 +unsigned long find_first_zero_bit(const unsigned long *addr, unsigned long size)
1515 +{
1516 + unsigned long idx;
1517 +
1518 + for (idx = 0; idx * BITS_PER_LONG < size; idx++) {
1519 + if (addr[idx] != ~0UL)
1520 + return min(idx * BITS_PER_LONG + ffz(addr[idx]), size);
1521 + }
1522 +
1523 + return size;
1524 +}
1525 +#endif
1526 +
1527 +#ifndef find_next_zero_bit
1528 +unsigned long find_next_zero_bit(const unsigned long *addr, unsigned long size,
1529 + unsigned long offset)
1530 +{
1531 + return _find_next_bit(addr, size, offset, ~0UL);
1532 +}
1533 +#endif
1534 diff --git a/tools/objtool/Build b/tools/objtool/Build
1535 index d6cdece5e58b..749becdf5b90 100644
1536 --- a/tools/objtool/Build
1537 +++ b/tools/objtool/Build
1538 @@ -1,5 +1,9 @@
1539 objtool-y += arch/$(SRCARCH)/
1540 objtool-y += builtin-check.o
1541 +objtool-y += builtin-orc.o
1542 +objtool-y += check.o
1543 +objtool-y += orc_gen.o
1544 +objtool-y += orc_dump.o
1545 objtool-y += elf.o
1546 objtool-y += special.o
1547 objtool-y += objtool.o
1548 diff --git a/tools/objtool/Documentation/stack-validation.txt b/tools/objtool/Documentation/stack-validation.txt
1549 index 55a60d331f47..3995735a878f 100644
1550 --- a/tools/objtool/Documentation/stack-validation.txt
1551 +++ b/tools/objtool/Documentation/stack-validation.txt
1552 @@ -11,9 +11,6 @@ analyzes every .o file and ensures the validity of its stack metadata.
1553 It enforces a set of rules on asm code and C inline assembly code so
1554 that stack traces can be reliable.
1555
1556 -Currently it only checks frame pointer usage, but there are plans to add
1557 -CFI validation for C files and CFI generation for asm files.
1558 -
1559 For each function, it recursively follows all possible code paths and
1560 validates the correct frame pointer state at each instruction.
1561
1562 @@ -23,6 +20,10 @@ alternative execution paths to a given instruction (or set of
1563 instructions). Similarly, it knows how to follow switch statements, for
1564 which gcc sometimes uses jump tables.
1565
1566 +(Objtool also has an 'orc generate' subcommand which generates debuginfo
1567 +for the ORC unwinder. See Documentation/x86/orc-unwinder.txt in the
1568 +kernel tree for more details.)
1569 +
1570
1571 Why do we need stack metadata validation?
1572 -----------------------------------------
1573 @@ -93,62 +94,24 @@ a) More reliable stack traces for frame pointer enabled kernels
1574 or at the very end of the function after the stack frame has been
1575 destroyed. This is an inherent limitation of frame pointers.
1576
1577 -b) 100% reliable stack traces for DWARF enabled kernels
1578 -
1579 - (NOTE: This is not yet implemented)
1580 -
1581 - As an alternative to frame pointers, DWARF Call Frame Information
1582 - (CFI) metadata can be used to walk the stack. Unlike frame pointers,
1583 - CFI metadata is out of band. So it doesn't affect runtime
1584 - performance and it can be reliable even when interrupts or exceptions
1585 - are involved.
1586 -
1587 - For C code, gcc automatically generates DWARF CFI metadata. But for
1588 - asm code, generating CFI is a tedious manual approach which requires
1589 - manually placed .cfi assembler macros to be scattered throughout the
1590 - code. It's clumsy and very easy to get wrong, and it makes the real
1591 - code harder to read.
1592 -
1593 - Stacktool will improve this situation in several ways. For code
1594 - which already has CFI annotations, it will validate them. For code
1595 - which doesn't have CFI annotations, it will generate them. So an
1596 - architecture can opt to strip out all the manual .cfi annotations
1597 - from their asm code and have objtool generate them instead.
1598 +b) ORC (Oops Rewind Capability) unwind table generation
1599
1600 - We might also add a runtime stack validation debug option where we
1601 - periodically walk the stack from schedule() and/or an NMI to ensure
1602 - that the stack metadata is sane and that we reach the bottom of the
1603 - stack.
1604 + An alternative to frame pointers and DWARF, ORC unwind data can be
1605 + used to walk the stack. Unlike frame pointers, ORC data is out of
1606 + band. So it doesn't affect runtime performance and it can be
1607 + reliable even when interrupts or exceptions are involved.
1608
1609 - So the benefit of objtool here will be that external tooling should
1610 - always show perfect stack traces. And the same will be true for
1611 - kernel warning/oops traces if the architecture has a runtime DWARF
1612 - unwinder.
1613 + For more details, see Documentation/x86/orc-unwinder.txt.
1614
1615 c) Higher live patching compatibility rate
1616
1617 - (NOTE: This is not yet implemented)
1618 -
1619 - Currently with CONFIG_LIVEPATCH there's a basic live patching
1620 - framework which is safe for roughly 85-90% of "security" fixes. But
1621 - patches can't have complex features like function dependency or
1622 - prototype changes, or data structure changes.
1623 -
1624 - There's a strong need to support patches which have the more complex
1625 - features so that the patch compatibility rate for security fixes can
1626 - eventually approach something resembling 100%. To achieve that, a
1627 - "consistency model" is needed, which allows tasks to be safely
1628 - transitioned from an unpatched state to a patched state.
1629 -
1630 - One of the key requirements of the currently proposed livepatch
1631 - consistency model [*] is that it needs to walk the stack of each
1632 - sleeping task to determine if it can be transitioned to the patched
1633 - state. If objtool can ensure that stack traces are reliable, this
1634 - consistency model can be used and the live patching compatibility
1635 - rate can be improved significantly.
1636 -
1637 - [*] https://lkml.kernel.org/r/cover.1423499826.git.jpoimboe@redhat.com
1638 + Livepatch has an optional "consistency model", which is needed for
1639 + more complex patches. In order for the consistency model to work,
1640 + stack traces need to be reliable (or an unreliable condition needs to
1641 + be detectable). Objtool makes that possible.
1642
1643 + For more details, see the livepatch documentation in the Linux kernel
1644 + source tree at Documentation/livepatch/livepatch.txt.
1645
1646 Rules
1647 -----
1648 @@ -201,80 +164,84 @@ To achieve the validation, objtool enforces the following rules:
1649 return normally.
1650
1651
1652 -Errors in .S files
1653 -------------------
1654 +Objtool warnings
1655 +----------------
1656 +
1657 +For asm files, if you're getting an error which doesn't make sense,
1658 +first make sure that the affected code follows the above rules.
1659
1660 -If you're getting an error in a compiled .S file which you don't
1661 -understand, first make sure that the affected code follows the above
1662 -rules.
1663 +For C files, the common culprits are inline asm statements and calls to
1664 +"noreturn" functions. See below for more details.
1665 +
1666 +Another possible cause for errors in C code is if the Makefile removes
1667 +-fno-omit-frame-pointer or adds -fomit-frame-pointer to the gcc options.
1668
1669 Here are some examples of common warnings reported by objtool, what
1670 they mean, and suggestions for how to fix them.
1671
1672
1673 -1. asm_file.o: warning: objtool: func()+0x128: call without frame pointer save/setup
1674 +1. file.o: warning: objtool: func()+0x128: call without frame pointer save/setup
1675
1676 The func() function made a function call without first saving and/or
1677 - updating the frame pointer.
1678 -
1679 - If func() is indeed a callable function, add proper frame pointer
1680 - logic using the FRAME_BEGIN and FRAME_END macros. Otherwise, remove
1681 - its ELF function annotation by changing ENDPROC to END.
1682 -
1683 - If you're getting this error in a .c file, see the "Errors in .c
1684 - files" section.
1685 + updating the frame pointer, and CONFIG_FRAME_POINTER is enabled.
1686
1687 + If the error is for an asm file, and func() is indeed a callable
1688 + function, add proper frame pointer logic using the FRAME_BEGIN and
1689 + FRAME_END macros. Otherwise, if it's not a callable function, remove
1690 + its ELF function annotation by changing ENDPROC to END, and instead
1691 + use the manual unwind hint macros in asm/unwind_hints.h.
1692
1693 -2. asm_file.o: warning: objtool: .text+0x53: return instruction outside of a callable function
1694 + If it's a GCC-compiled .c file, the error may be because the function
1695 + uses an inline asm() statement which has a "call" instruction. An
1696 + asm() statement with a call instruction must declare the use of the
1697 + stack pointer in its output operand. On x86_64, this means adding
1698 + the ASM_CALL_CONSTRAINT as an output constraint:
1699
1700 - A return instruction was detected, but objtool couldn't find a way
1701 - for a callable function to reach the instruction.
1702 + asm volatile("call func" : ASM_CALL_CONSTRAINT);
1703
1704 - If the return instruction is inside (or reachable from) a callable
1705 - function, the function needs to be annotated with the ENTRY/ENDPROC
1706 - macros.
1707 + Otherwise the stack frame may not get created before the call.
1708
1709 - If you _really_ need a return instruction outside of a function, and
1710 - are 100% sure that it won't affect stack traces, you can tell
1711 - objtool to ignore it. See the "Adding exceptions" section below.
1712
1713 +2. file.o: warning: objtool: .text+0x53: unreachable instruction
1714
1715 -3. asm_file.o: warning: objtool: func()+0x9: function has unreachable instruction
1716 + Objtool couldn't find a code path to reach the instruction.
1717
1718 - The instruction lives inside of a callable function, but there's no
1719 - possible control flow path from the beginning of the function to the
1720 - instruction.
1721 + If the error is for an asm file, and the instruction is inside (or
1722 + reachable from) a callable function, the function should be annotated
1723 + with the ENTRY/ENDPROC macros (ENDPROC is the important one).
1724 + Otherwise, the code should probably be annotated with the unwind hint
1725 + macros in asm/unwind_hints.h so objtool and the unwinder can know the
1726 + stack state associated with the code.
1727
1728 - If the instruction is actually needed, and it's actually in a
1729 - callable function, ensure that its function is properly annotated
1730 - with ENTRY/ENDPROC.
1731 + If you're 100% sure the code won't affect stack traces, or if you're
1732 + a just a bad person, you can tell objtool to ignore it. See the
1733 + "Adding exceptions" section below.
1734
1735 If it's not actually in a callable function (e.g. kernel entry code),
1736 change ENDPROC to END.
1737
1738
1739 -4. asm_file.o: warning: objtool: func(): can't find starting instruction
1740 +4. file.o: warning: objtool: func(): can't find starting instruction
1741 or
1742 - asm_file.o: warning: objtool: func()+0x11dd: can't decode instruction
1743 + file.o: warning: objtool: func()+0x11dd: can't decode instruction
1744
1745 - Did you put data in a text section? If so, that can confuse
1746 + Does the file have data in a text section? If so, that can confuse
1747 objtool's instruction decoder. Move the data to a more appropriate
1748 section like .data or .rodata.
1749
1750
1751 -5. asm_file.o: warning: objtool: func()+0x6: kernel entry/exit from callable instruction
1752 -
1753 - This is a kernel entry/exit instruction like sysenter or sysret.
1754 - Such instructions aren't allowed in a callable function, and are most
1755 - likely part of the kernel entry code.
1756 +5. file.o: warning: objtool: func()+0x6: unsupported instruction in callable function
1757
1758 - If the instruction isn't actually in a callable function, change
1759 - ENDPROC to END.
1760 + This is a kernel entry/exit instruction like sysenter or iret. Such
1761 + instructions aren't allowed in a callable function, and are most
1762 + likely part of the kernel entry code. They should usually not have
1763 + the callable function annotation (ENDPROC) and should always be
1764 + annotated with the unwind hint macros in asm/unwind_hints.h.
1765
1766
1767 -6. asm_file.o: warning: objtool: func()+0x26: sibling call from callable instruction with changed frame pointer
1768 +6. file.o: warning: objtool: func()+0x26: sibling call from callable instruction with modified stack frame
1769
1770 - This is a dynamic jump or a jump to an undefined symbol. Stacktool
1771 + This is a dynamic jump or a jump to an undefined symbol. Objtool
1772 assumed it's a sibling call and detected that the frame pointer
1773 wasn't first restored to its original state.
1774
1775 @@ -282,24 +249,28 @@ they mean, and suggestions for how to fix them.
1776 destination code to the local file.
1777
1778 If the instruction is not actually in a callable function (e.g.
1779 - kernel entry code), change ENDPROC to END.
1780 + kernel entry code), change ENDPROC to END and annotate manually with
1781 + the unwind hint macros in asm/unwind_hints.h.
1782
1783
1784 -7. asm_file: warning: objtool: func()+0x5c: frame pointer state mismatch
1785 +7. file: warning: objtool: func()+0x5c: stack state mismatch
1786
1787 The instruction's frame pointer state is inconsistent, depending on
1788 which execution path was taken to reach the instruction.
1789
1790 - Make sure the function pushes and sets up the frame pointer (for
1791 - x86_64, this means rbp) at the beginning of the function and pops it
1792 - at the end of the function. Also make sure that no other code in the
1793 - function touches the frame pointer.
1794 + Make sure that, when CONFIG_FRAME_POINTER is enabled, the function
1795 + pushes and sets up the frame pointer (for x86_64, this means rbp) at
1796 + the beginning of the function and pops it at the end of the function.
1797 + Also make sure that no other code in the function touches the frame
1798 + pointer.
1799
1800 + Another possibility is that the code has some asm or inline asm which
1801 + does some unusual things to the stack or the frame pointer. In such
1802 + cases it's probably appropriate to use the unwind hint macros in
1803 + asm/unwind_hints.h.
1804
1805 -Errors in .c files
1806 -------------------
1807
1808 -1. c_file.o: warning: objtool: funcA() falls through to next function funcB()
1809 +8. file.o: warning: objtool: funcA() falls through to next function funcB()
1810
1811 This means that funcA() doesn't end with a return instruction or an
1812 unconditional jump, and that objtool has determined that the function
1813 @@ -318,22 +289,6 @@ Errors in .c files
1814 might be corrupt due to a gcc bug. For more details, see:
1815 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70646
1816
1817 -2. If you're getting any other objtool error in a compiled .c file, it
1818 - may be because the file uses an asm() statement which has a "call"
1819 - instruction. An asm() statement with a call instruction must declare
1820 - the use of the stack pointer in its output operand. For example, on
1821 - x86_64:
1822 -
1823 - register void *__sp asm("rsp");
1824 - asm volatile("call func" : "+r" (__sp));
1825 -
1826 - Otherwise the stack frame may not get created before the call.
1827 -
1828 -3. Another possible cause for errors in C code is if the Makefile removes
1829 - -fno-omit-frame-pointer or adds -fomit-frame-pointer to the gcc options.
1830 -
1831 -Also see the above section for .S file errors for more information what
1832 -the individual error messages mean.
1833
1834 If the error doesn't seem to make sense, it could be a bug in objtool.
1835 Feel free to ask the objtool maintainer for help.
1836 diff --git a/tools/objtool/Makefile b/tools/objtool/Makefile
1837 index 041b493ad3ab..e6acc281dd37 100644
1838 --- a/tools/objtool/Makefile
1839 +++ b/tools/objtool/Makefile
1840 @@ -1,3 +1,4 @@
1841 +# SPDX-License-Identifier: GPL-2.0
1842 include ../scripts/Makefile.include
1843 include ../scripts/Makefile.arch
1844
1845 @@ -6,17 +7,19 @@ ARCH := x86
1846 endif
1847
1848 # always use the host compiler
1849 -CC = gcc
1850 -LD = ld
1851 -AR = ar
1852 +HOSTCC ?= gcc
1853 +HOSTLD ?= ld
1854 +CC = $(HOSTCC)
1855 +LD = $(HOSTLD)
1856 +AR = ar
1857
1858 ifeq ($(srctree),)
1859 -srctree := $(patsubst %/,%,$(dir $(shell pwd)))
1860 +srctree := $(patsubst %/,%,$(dir $(CURDIR)))
1861 srctree := $(patsubst %/,%,$(dir $(srctree)))
1862 endif
1863
1864 SUBCMD_SRCDIR = $(srctree)/tools/lib/subcmd/
1865 -LIBSUBCMD_OUTPUT = $(if $(OUTPUT),$(OUTPUT),$(PWD)/)
1866 +LIBSUBCMD_OUTPUT = $(if $(OUTPUT),$(OUTPUT),$(CURDIR)/)
1867 LIBSUBCMD = $(LIBSUBCMD_OUTPUT)libsubcmd.a
1868
1869 OBJTOOL := $(OUTPUT)objtool
1870 @@ -24,8 +27,11 @@ OBJTOOL_IN := $(OBJTOOL)-in.o
1871
1872 all: $(OBJTOOL)
1873
1874 -INCLUDES := -I$(srctree)/tools/include -I$(srctree)/tools/arch/$(HOSTARCH)/include/uapi
1875 -CFLAGS += -Wall -Werror $(EXTRA_WARNINGS) -fomit-frame-pointer -O2 -g $(INCLUDES)
1876 +INCLUDES := -I$(srctree)/tools/include \
1877 + -I$(srctree)/tools/arch/$(HOSTARCH)/include/uapi \
1878 + -I$(srctree)/tools/objtool/arch/$(ARCH)/include
1879 +WARNINGS := $(EXTRA_WARNINGS) -Wno-switch-default -Wno-switch-enum -Wno-packed
1880 +CFLAGS += -Wall -Werror $(WARNINGS) -fomit-frame-pointer -O2 -g $(INCLUDES)
1881 LDFLAGS += -lelf $(LIBSUBCMD)
1882
1883 # Allow old libelf to be used:
1884 @@ -39,19 +45,8 @@ include $(srctree)/tools/build/Makefile.include
1885 $(OBJTOOL_IN): fixdep FORCE
1886 @$(MAKE) $(build)=objtool
1887
1888 -# Busybox's diff doesn't have -I, avoid warning in that case
1889 -#
1890 $(OBJTOOL): $(LIBSUBCMD) $(OBJTOOL_IN)
1891 - @(diff -I 2>&1 | grep -q 'option requires an argument' && \
1892 - test -d ../../kernel -a -d ../../tools -a -d ../objtool && (( \
1893 - diff -I'^#include' arch/x86/insn/insn.c ../../arch/x86/lib/insn.c >/dev/null && \
1894 - diff -I'^#include' arch/x86/insn/inat.c ../../arch/x86/lib/inat.c >/dev/null && \
1895 - diff arch/x86/insn/x86-opcode-map.txt ../../arch/x86/lib/x86-opcode-map.txt >/dev/null && \
1896 - diff arch/x86/insn/gen-insn-attr-x86.awk ../../arch/x86/tools/gen-insn-attr-x86.awk >/dev/null && \
1897 - diff -I'^#include' arch/x86/insn/insn.h ../../arch/x86/include/asm/insn.h >/dev/null && \
1898 - diff -I'^#include' arch/x86/insn/inat.h ../../arch/x86/include/asm/inat.h >/dev/null && \
1899 - diff -I'^#include' arch/x86/insn/inat_types.h ../../arch/x86/include/asm/inat_types.h >/dev/null) \
1900 - || echo "warning: objtool: x86 instruction decoder differs from kernel" >&2 )) || true
1901 + @$(CONFIG_SHELL) ./sync-check.sh
1902 $(QUIET_LINK)$(CC) $(OBJTOOL_IN) $(LDFLAGS) -o $@
1903
1904
1905 @@ -61,7 +56,7 @@ $(LIBSUBCMD): fixdep FORCE
1906 clean:
1907 $(call QUIET_CLEAN, objtool) $(RM) $(OBJTOOL)
1908 $(Q)find $(OUTPUT) -name '*.o' -delete -o -name '\.*.cmd' -delete -o -name '\.*.d' -delete
1909 - $(Q)$(RM) $(OUTPUT)arch/x86/insn/inat-tables.c $(OUTPUT)fixdep
1910 + $(Q)$(RM) $(OUTPUT)arch/x86/lib/inat-tables.c $(OUTPUT)fixdep
1911
1912 FORCE:
1913
1914 diff --git a/tools/objtool/arch.h b/tools/objtool/arch.h
1915 index f7350fcedc70..b0d7dc3d71b5 100644
1916 --- a/tools/objtool/arch.h
1917 +++ b/tools/objtool/arch.h
1918 @@ -19,26 +19,64 @@
1919 #define _ARCH_H
1920
1921 #include <stdbool.h>
1922 +#include <linux/list.h>
1923 #include "elf.h"
1924 +#include "cfi.h"
1925
1926 -#define INSN_FP_SAVE 1
1927 -#define INSN_FP_SETUP 2
1928 -#define INSN_FP_RESTORE 3
1929 -#define INSN_JUMP_CONDITIONAL 4
1930 -#define INSN_JUMP_UNCONDITIONAL 5
1931 -#define INSN_JUMP_DYNAMIC 6
1932 -#define INSN_CALL 7
1933 -#define INSN_CALL_DYNAMIC 8
1934 -#define INSN_RETURN 9
1935 -#define INSN_CONTEXT_SWITCH 10
1936 -#define INSN_BUG 11
1937 -#define INSN_NOP 12
1938 -#define INSN_OTHER 13
1939 +#define INSN_JUMP_CONDITIONAL 1
1940 +#define INSN_JUMP_UNCONDITIONAL 2
1941 +#define INSN_JUMP_DYNAMIC 3
1942 +#define INSN_CALL 4
1943 +#define INSN_CALL_DYNAMIC 5
1944 +#define INSN_RETURN 6
1945 +#define INSN_CONTEXT_SWITCH 7
1946 +#define INSN_STACK 8
1947 +#define INSN_BUG 9
1948 +#define INSN_NOP 10
1949 +#define INSN_OTHER 11
1950 #define INSN_LAST INSN_OTHER
1951
1952 +enum op_dest_type {
1953 + OP_DEST_REG,
1954 + OP_DEST_REG_INDIRECT,
1955 + OP_DEST_MEM,
1956 + OP_DEST_PUSH,
1957 + OP_DEST_LEAVE,
1958 +};
1959 +
1960 +struct op_dest {
1961 + enum op_dest_type type;
1962 + unsigned char reg;
1963 + int offset;
1964 +};
1965 +
1966 +enum op_src_type {
1967 + OP_SRC_REG,
1968 + OP_SRC_REG_INDIRECT,
1969 + OP_SRC_CONST,
1970 + OP_SRC_POP,
1971 + OP_SRC_ADD,
1972 + OP_SRC_AND,
1973 +};
1974 +
1975 +struct op_src {
1976 + enum op_src_type type;
1977 + unsigned char reg;
1978 + int offset;
1979 +};
1980 +
1981 +struct stack_op {
1982 + struct op_dest dest;
1983 + struct op_src src;
1984 +};
1985 +
1986 +void arch_initial_func_cfi_state(struct cfi_state *state);
1987 +
1988 int arch_decode_instruction(struct elf *elf, struct section *sec,
1989 unsigned long offset, unsigned int maxlen,
1990 unsigned int *len, unsigned char *type,
1991 - unsigned long *displacement);
1992 + unsigned long *immediate, struct stack_op *op);
1993 +
1994 +bool arch_callee_saved_reg(unsigned char reg);
1995
1996 #endif /* _ARCH_H */
1997 diff --git a/tools/objtool/arch/x86/Build b/tools/objtool/arch/x86/Build
1998 index debbdb0b5c43..b998412c017d 100644
1999 --- a/tools/objtool/arch/x86/Build
2000 +++ b/tools/objtool/arch/x86/Build
2001 @@ -1,12 +1,12 @@
2002 objtool-y += decode.o
2003
2004 -inat_tables_script = arch/x86/insn/gen-insn-attr-x86.awk
2005 -inat_tables_maps = arch/x86/insn/x86-opcode-map.txt
2006 +inat_tables_script = arch/x86/tools/gen-insn-attr-x86.awk
2007 +inat_tables_maps = arch/x86/lib/x86-opcode-map.txt
2008
2009 -$(OUTPUT)arch/x86/insn/inat-tables.c: $(inat_tables_script) $(inat_tables_maps)
2010 +$(OUTPUT)arch/x86/lib/inat-tables.c: $(inat_tables_script) $(inat_tables_maps)
2011 $(call rule_mkdir)
2012 $(Q)$(call echo-cmd,gen)$(AWK) -f $(inat_tables_script) $(inat_tables_maps) > $@
2013
2014 -$(OUTPUT)arch/x86/decode.o: $(OUTPUT)arch/x86/insn/inat-tables.c
2015 +$(OUTPUT)arch/x86/decode.o: $(OUTPUT)arch/x86/lib/inat-tables.c
2016
2017 -CFLAGS_decode.o += -I$(OUTPUT)arch/x86/insn
2018 +CFLAGS_decode.o += -I$(OUTPUT)arch/x86/lib
2019 diff --git a/tools/objtool/arch/x86/decode.c b/tools/objtool/arch/x86/decode.c
2020 index 039636ffb6c8..540a209b78ab 100644
2021 --- a/tools/objtool/arch/x86/decode.c
2022 +++ b/tools/objtool/arch/x86/decode.c
2023 @@ -19,14 +19,25 @@
2024 #include <stdlib.h>
2025
2026 #define unlikely(cond) (cond)
2027 -#include "insn/insn.h"
2028 -#include "insn/inat.c"
2029 -#include "insn/insn.c"
2030 +#include <asm/insn.h>
2031 +#include "lib/inat.c"
2032 +#include "lib/insn.c"
2033
2034 #include "../../elf.h"
2035 #include "../../arch.h"
2036 #include "../../warn.h"
2037
2038 +static unsigned char op_to_cfi_reg[][2] = {
2039 + {CFI_AX, CFI_R8},
2040 + {CFI_CX, CFI_R9},
2041 + {CFI_DX, CFI_R10},
2042 + {CFI_BX, CFI_R11},
2043 + {CFI_SP, CFI_R12},
2044 + {CFI_BP, CFI_R13},
2045 + {CFI_SI, CFI_R14},
2046 + {CFI_DI, CFI_R15},
2047 +};
2048 +
2049 static int is_x86_64(struct elf *elf)
2050 {
2051 switch (elf->ehdr.e_machine) {
2052 @@ -40,24 +51,50 @@ static int is_x86_64(struct elf *elf)
2053 }
2054 }
2055
2056 +bool arch_callee_saved_reg(unsigned char reg)
2057 +{
2058 + switch (reg) {
2059 + case CFI_BP:
2060 + case CFI_BX:
2061 + case CFI_R12:
2062 + case CFI_R13:
2063 + case CFI_R14:
2064 + case CFI_R15:
2065 + return true;
2066 +
2067 + case CFI_AX:
2068 + case CFI_CX:
2069 + case CFI_DX:
2070 + case CFI_SI:
2071 + case CFI_DI:
2072 + case CFI_SP:
2073 + case CFI_R8:
2074 + case CFI_R9:
2075 + case CFI_R10:
2076 + case CFI_R11:
2077 + case CFI_RA:
2078 + default:
2079 + return false;
2080 + }
2081 +}
2082 +
2083 int arch_decode_instruction(struct elf *elf, struct section *sec,
2084 unsigned long offset, unsigned int maxlen,
2085 unsigned int *len, unsigned char *type,
2086 - unsigned long *immediate)
2087 + unsigned long *immediate, struct stack_op *op)
2088 {
2089 struct insn insn;
2090 - int x86_64;
2091 - unsigned char op1, op2, ext;
2092 + int x86_64, sign;
2093 + unsigned char op1, op2, rex = 0, rex_b = 0, rex_r = 0, rex_w = 0,
2094 + rex_x = 0, modrm = 0, modrm_mod = 0, modrm_rm = 0,
2095 + modrm_reg = 0, sib = 0;
2096
2097 x86_64 = is_x86_64(elf);
2098 if (x86_64 == -1)
2099 return -1;
2100
2101 - insn_init(&insn, (void *)(sec->data + offset), maxlen, x86_64);
2102 + insn_init(&insn, sec->data->d_buf + offset, maxlen, x86_64);
2103 insn_get_length(&insn);
2104 - insn_get_opcode(&insn);
2105 - insn_get_modrm(&insn);
2106 - insn_get_immediate(&insn);
2107
2108 if (!insn_complete(&insn)) {
2109 WARN_FUNC("can't decode instruction", sec, offset);
2110 @@ -73,70 +110,317 @@ int arch_decode_instruction(struct elf *elf, struct section *sec,
2111 op1 = insn.opcode.bytes[0];
2112 op2 = insn.opcode.bytes[1];
2113
2114 + if (insn.rex_prefix.nbytes) {
2115 + rex = insn.rex_prefix.bytes[0];
2116 + rex_w = X86_REX_W(rex) >> 3;
2117 + rex_r = X86_REX_R(rex) >> 2;
2118 + rex_x = X86_REX_X(rex) >> 1;
2119 + rex_b = X86_REX_B(rex);
2120 + }
2121 +
2122 + if (insn.modrm.nbytes) {
2123 + modrm = insn.modrm.bytes[0];
2124 + modrm_mod = X86_MODRM_MOD(modrm);
2125 + modrm_reg = X86_MODRM_REG(modrm);
2126 + modrm_rm = X86_MODRM_RM(modrm);
2127 + }
2128 +
2129 + if (insn.sib.nbytes)
2130 + sib = insn.sib.bytes[0];
2131 +
2132 switch (op1) {
2133 - case 0x55:
2134 - if (!insn.rex_prefix.nbytes)
2135 - /* push rbp */
2136 - *type = INSN_FP_SAVE;
2137 +
2138 + case 0x1:
2139 + case 0x29:
2140 + if (rex_w && !rex_b && modrm_mod == 3 && modrm_rm == 4) {
2141 +
2142 + /* add/sub reg, %rsp */
2143 + *type = INSN_STACK;
2144 + op->src.type = OP_SRC_ADD;
2145 + op->src.reg = op_to_cfi_reg[modrm_reg][rex_r];
2146 + op->dest.type = OP_DEST_REG;
2147 + op->dest.reg = CFI_SP;
2148 + }
2149 + break;
2150 +
2151 + case 0x50 ... 0x57:
2152 +
2153 + /* push reg */
2154 + *type = INSN_STACK;
2155 + op->src.type = OP_SRC_REG;
2156 + op->src.reg = op_to_cfi_reg[op1 & 0x7][rex_b];
2157 + op->dest.type = OP_DEST_PUSH;
2158 +
2159 + break;
2160 +
2161 + case 0x58 ... 0x5f:
2162 +
2163 + /* pop reg */
2164 + *type = INSN_STACK;
2165 + op->src.type = OP_SRC_POP;
2166 + op->dest.type = OP_DEST_REG;
2167 + op->dest.reg = op_to_cfi_reg[op1 & 0x7][rex_b];
2168 +
2169 break;
2170
2171 - case 0x5d:
2172 - if (!insn.rex_prefix.nbytes)
2173 - /* pop rbp */
2174 - *type = INSN_FP_RESTORE;
2175 + case 0x68:
2176 + case 0x6a:
2177 + /* push immediate */
2178 + *type = INSN_STACK;
2179 + op->src.type = OP_SRC_CONST;
2180 + op->dest.type = OP_DEST_PUSH;
2181 break;
2182
2183 case 0x70 ... 0x7f:
2184 *type = INSN_JUMP_CONDITIONAL;
2185 break;
2186
2187 + case 0x81:
2188 + case 0x83:
2189 + if (rex != 0x48)
2190 + break;
2191 +
2192 + if (modrm == 0xe4) {
2193 + /* and imm, %rsp */
2194 + *type = INSN_STACK;
2195 + op->src.type = OP_SRC_AND;
2196 + op->src.reg = CFI_SP;
2197 + op->src.offset = insn.immediate.value;
2198 + op->dest.type = OP_DEST_REG;
2199 + op->dest.reg = CFI_SP;
2200 + break;
2201 + }
2202 +
2203 + if (modrm == 0xc4)
2204 + sign = 1;
2205 + else if (modrm == 0xec)
2206 + sign = -1;
2207 + else
2208 + break;
2209 +
2210 + /* add/sub imm, %rsp */
2211 + *type = INSN_STACK;
2212 + op->src.type = OP_SRC_ADD;
2213 + op->src.reg = CFI_SP;
2214 + op->src.offset = insn.immediate.value * sign;
2215 + op->dest.type = OP_DEST_REG;
2216 + op->dest.reg = CFI_SP;
2217 + break;
2218 +
2219 case 0x89:
2220 - if (insn.rex_prefix.nbytes == 1 &&
2221 - insn.rex_prefix.bytes[0] == 0x48 &&
2222 - insn.modrm.nbytes && insn.modrm.bytes[0] == 0xe5)
2223 - /* mov rsp, rbp */
2224 - *type = INSN_FP_SETUP;
2225 + if (rex_w && !rex_r && modrm_mod == 3 && modrm_reg == 4) {
2226 +
2227 + /* mov %rsp, reg */
2228 + *type = INSN_STACK;
2229 + op->src.type = OP_SRC_REG;
2230 + op->src.reg = CFI_SP;
2231 + op->dest.type = OP_DEST_REG;
2232 + op->dest.reg = op_to_cfi_reg[modrm_rm][rex_b];
2233 + break;
2234 + }
2235 +
2236 + if (rex_w && !rex_b && modrm_mod == 3 && modrm_rm == 4) {
2237 +
2238 + /* mov reg, %rsp */
2239 + *type = INSN_STACK;
2240 + op->src.type = OP_SRC_REG;
2241 + op->src.reg = op_to_cfi_reg[modrm_reg][rex_r];
2242 + op->dest.type = OP_DEST_REG;
2243 + op->dest.reg = CFI_SP;
2244 + break;
2245 + }
2246 +
2247 + /* fallthrough */
2248 + case 0x88:
2249 + if (!rex_b &&
2250 + (modrm_mod == 1 || modrm_mod == 2) && modrm_rm == 5) {
2251 +
2252 + /* mov reg, disp(%rbp) */
2253 + *type = INSN_STACK;
2254 + op->src.type = OP_SRC_REG;
2255 + op->src.reg = op_to_cfi_reg[modrm_reg][rex_r];
2256 + op->dest.type = OP_DEST_REG_INDIRECT;
2257 + op->dest.reg = CFI_BP;
2258 + op->dest.offset = insn.displacement.value;
2259 +
2260 + } else if (rex_w && !rex_b && modrm_rm == 4 && sib == 0x24) {
2261 +
2262 + /* mov reg, disp(%rsp) */
2263 + *type = INSN_STACK;
2264 + op->src.type = OP_SRC_REG;
2265 + op->src.reg = op_to_cfi_reg[modrm_reg][rex_r];
2266 + op->dest.type = OP_DEST_REG_INDIRECT;
2267 + op->dest.reg = CFI_SP;
2268 + op->dest.offset = insn.displacement.value;
2269 + }
2270 +
2271 + break;
2272 +
2273 + case 0x8b:
2274 + if (rex_w && !rex_b && modrm_mod == 1 && modrm_rm == 5) {
2275 +
2276 + /* mov disp(%rbp), reg */
2277 + *type = INSN_STACK;
2278 + op->src.type = OP_SRC_REG_INDIRECT;
2279 + op->src.reg = CFI_BP;
2280 + op->src.offset = insn.displacement.value;
2281 + op->dest.type = OP_DEST_REG;
2282 + op->dest.reg = op_to_cfi_reg[modrm_reg][rex_r];
2283 +
2284 + } else if (rex_w && !rex_b && sib == 0x24 &&
2285 + modrm_mod != 3 && modrm_rm == 4) {
2286 +
2287 + /* mov disp(%rsp), reg */
2288 + *type = INSN_STACK;
2289 + op->src.type = OP_SRC_REG_INDIRECT;
2290 + op->src.reg = CFI_SP;
2291 + op->src.offset = insn.displacement.value;
2292 + op->dest.type = OP_DEST_REG;
2293 + op->dest.reg = op_to_cfi_reg[modrm_reg][rex_r];
2294 + }
2295 +
2296 break;
2297
2298 case 0x8d:
2299 - if (insn.rex_prefix.nbytes &&
2300 - insn.rex_prefix.bytes[0] == 0x48 &&
2301 - insn.modrm.nbytes && insn.modrm.bytes[0] == 0x2c &&
2302 - insn.sib.nbytes && insn.sib.bytes[0] == 0x24)
2303 - /* lea %(rsp), %rbp */
2304 - *type = INSN_FP_SETUP;
2305 + if (sib == 0x24 && rex_w && !rex_b && !rex_x) {
2306 +
2307 + *type = INSN_STACK;
2308 + if (!insn.displacement.value) {
2309 + /* lea (%rsp), reg */
2310 + op->src.type = OP_SRC_REG;
2311 + } else {
2312 + /* lea disp(%rsp), reg */
2313 + op->src.type = OP_SRC_ADD;
2314 + op->src.offset = insn.displacement.value;
2315 + }
2316 + op->src.reg = CFI_SP;
2317 + op->dest.type = OP_DEST_REG;
2318 + op->dest.reg = op_to_cfi_reg[modrm_reg][rex_r];
2319 +
2320 + } else if (rex == 0x48 && modrm == 0x65) {
2321 +
2322 + /* lea disp(%rbp), %rsp */
2323 + *type = INSN_STACK;
2324 + op->src.type = OP_SRC_ADD;
2325 + op->src.reg = CFI_BP;
2326 + op->src.offset = insn.displacement.value;
2327 + op->dest.type = OP_DEST_REG;
2328 + op->dest.reg = CFI_SP;
2329 +
2330 + } else if (rex == 0x49 && modrm == 0x62 &&
2331 + insn.displacement.value == -8) {
2332 +
2333 + /*
2334 + * lea -0x8(%r10), %rsp
2335 + *
2336 + * Restoring rsp back to its original value after a
2337 + * stack realignment.
2338 + */
2339 + *type = INSN_STACK;
2340 + op->src.type = OP_SRC_ADD;
2341 + op->src.reg = CFI_R10;
2342 + op->src.offset = -8;
2343 + op->dest.type = OP_DEST_REG;
2344 + op->dest.reg = CFI_SP;
2345 +
2346 + } else if (rex == 0x49 && modrm == 0x65 &&
2347 + insn.displacement.value == -16) {
2348 +
2349 + /*
2350 + * lea -0x10(%r13), %rsp
2351 + *
2352 + * Restoring rsp back to its original value after a
2353 + * stack realignment.
2354 + */
2355 + *type = INSN_STACK;
2356 + op->src.type = OP_SRC_ADD;
2357 + op->src.reg = CFI_R13;
2358 + op->src.offset = -16;
2359 + op->dest.type = OP_DEST_REG;
2360 + op->dest.reg = CFI_SP;
2361 + }
2362 +
2363 + break;
2364 +
2365 + case 0x8f:
2366 + /* pop to mem */
2367 + *type = INSN_STACK;
2368 + op->src.type = OP_SRC_POP;
2369 + op->dest.type = OP_DEST_MEM;
2370 break;
2371
2372 case 0x90:
2373 *type = INSN_NOP;
2374 break;
2375
2376 + case 0x9c:
2377 + /* pushf */
2378 + *type = INSN_STACK;
2379 + op->src.type = OP_SRC_CONST;
2380 + op->dest.type = OP_DEST_PUSH;
2381 + break;
2382 +
2383 + case 0x9d:
2384 + /* popf */
2385 + *type = INSN_STACK;
2386 + op->src.type = OP_SRC_POP;
2387 + op->dest.type = OP_DEST_MEM;
2388 + break;
2389 +
2390 case 0x0f:
2391 - if (op2 >= 0x80 && op2 <= 0x8f)
2392 +
2393 + if (op2 >= 0x80 && op2 <= 0x8f) {
2394 +
2395 *type = INSN_JUMP_CONDITIONAL;
2396 - else if (op2 == 0x05 || op2 == 0x07 || op2 == 0x34 ||
2397 - op2 == 0x35)
2398 +
2399 + } else if (op2 == 0x05 || op2 == 0x07 || op2 == 0x34 ||
2400 + op2 == 0x35) {
2401 +
2402 /* sysenter, sysret */
2403 *type = INSN_CONTEXT_SWITCH;
2404 - else if (op2 == 0x0b || op2 == 0xb9)
2405 +
2406 + } else if (op2 == 0x0b || op2 == 0xb9) {
2407 +
2408 /* ud2 */
2409 *type = INSN_BUG;
2410 - else if (op2 == 0x0d || op2 == 0x1f)
2411 +
2412 + } else if (op2 == 0x0d || op2 == 0x1f) {
2413 +
2414 /* nopl/nopw */
2415 *type = INSN_NOP;
2416 - else if (op2 == 0x01 && insn.modrm.nbytes &&
2417 - (insn.modrm.bytes[0] == 0xc2 ||
2418 - insn.modrm.bytes[0] == 0xd8))
2419 - /* vmlaunch, vmrun */
2420 - *type = INSN_CONTEXT_SWITCH;
2421 +
2422 + } else if (op2 == 0xa0 || op2 == 0xa8) {
2423 +
2424 + /* push fs/gs */
2425 + *type = INSN_STACK;
2426 + op->src.type = OP_SRC_CONST;
2427 + op->dest.type = OP_DEST_PUSH;
2428 +
2429 + } else if (op2 == 0xa1 || op2 == 0xa9) {
2430 +
2431 + /* pop fs/gs */
2432 + *type = INSN_STACK;
2433 + op->src.type = OP_SRC_POP;
2434 + op->dest.type = OP_DEST_MEM;
2435 + }
2436
2437 break;
2438
2439 - case 0xc9: /* leave */
2440 - *type = INSN_FP_RESTORE;
2441 + case 0xc9:
2442 + /*
2443 + * leave
2444 + *
2445 + * equivalent to:
2446 + * mov bp, sp
2447 + * pop bp
2448 + */
2449 + *type = INSN_STACK;
2450 + op->dest.type = OP_DEST_LEAVE;
2451 +
2452 break;
2453
2454 - case 0xe3: /* jecxz/jrcxz */
2455 + case 0xe3:
2456 + /* jecxz/jrcxz */
2457 *type = INSN_JUMP_CONDITIONAL;
2458 break;
2459
2460 @@ -161,14 +445,27 @@ int arch_decode_instruction(struct elf *elf, struct section *sec,
2461 break;
2462
2463 case 0xff:
2464 - ext = X86_MODRM_REG(insn.modrm.bytes[0]);
2465 - if (ext == 2 || ext == 3)
2466 + if (modrm_reg == 2 || modrm_reg == 3)
2467 +
2468 *type = INSN_CALL_DYNAMIC;
2469 - else if (ext == 4)
2470 +
2471 + else if (modrm_reg == 4)
2472 +
2473 *type = INSN_JUMP_DYNAMIC;
2474 - else if (ext == 5) /*jmpf */
2475 +
2476 + else if (modrm_reg == 5)
2477 +
2478 + /* jmpf */
2479 *type = INSN_CONTEXT_SWITCH;
2480
2481 + else if (modrm_reg == 6) {
2482 +
2483 + /* push from mem */
2484 + *type = INSN_STACK;
2485 + op->src.type = OP_SRC_CONST;
2486 + op->dest.type = OP_DEST_PUSH;
2487 + }
2488 +
2489 break;
2490
2491 default:
2492 @@ -179,3 +476,21 @@ int arch_decode_instruction(struct elf *elf, struct section *sec,
2493
2494 return 0;
2495 }
2496 +
2497 +void arch_initial_func_cfi_state(struct cfi_state *state)
2498 +{
2499 + int i;
2500 +
2501 + for (i = 0; i < CFI_NUM_REGS; i++) {
2502 + state->regs[i].base = CFI_UNDEFINED;
2503 + state->regs[i].offset = 0;
2504 + }
2505 +
2506 + /* initial CFA (call frame address) */
2507 + state->cfa.base = CFI_SP;
2508 + state->cfa.offset = 8;
2509 +
2510 + /* initial RA (return address) */
2511 + state->regs[16].base = CFI_CFA;
2512 + state->regs[16].offset = -8;
2513 +}
2514 diff --git a/tools/objtool/arch/x86/include/asm/inat.h b/tools/objtool/arch/x86/include/asm/inat.h
2515 new file mode 100644
2516 index 000000000000..02aff0867211
2517 --- /dev/null
2518 +++ b/tools/objtool/arch/x86/include/asm/inat.h
2519 @@ -0,0 +1,234 @@
2520 +#ifndef _ASM_X86_INAT_H
2521 +#define _ASM_X86_INAT_H
2522 +/*
2523 + * x86 instruction attributes
2524 + *
2525 + * Written by Masami Hiramatsu <mhiramat@redhat.com>
2526 + *
2527 + * This program is free software; you can redistribute it and/or modify
2528 + * it under the terms of the GNU General Public License as published by
2529 + * the Free Software Foundation; either version 2 of the License, or
2530 + * (at your option) any later version.
2531 + *
2532 + * This program is distributed in the hope that it will be useful,
2533 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
2534 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2535 + * GNU General Public License for more details.
2536 + *
2537 + * You should have received a copy of the GNU General Public License
2538 + * along with this program; if not, write to the Free Software
2539 + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
2540 + *
2541 + */
2542 +#include <asm/inat_types.h>
2543 +
2544 +/*
2545 + * Internal bits. Don't use bitmasks directly, because these bits are
2546 + * unstable. You should use checking functions.
2547 + */
2548 +
2549 +#define INAT_OPCODE_TABLE_SIZE 256
2550 +#define INAT_GROUP_TABLE_SIZE 8
2551 +
2552 +/* Legacy last prefixes */
2553 +#define INAT_PFX_OPNDSZ 1 /* 0x66 */ /* LPFX1 */
2554 +#define INAT_PFX_REPE 2 /* 0xF3 */ /* LPFX2 */
2555 +#define INAT_PFX_REPNE 3 /* 0xF2 */ /* LPFX3 */
2556 +/* Other Legacy prefixes */
2557 +#define INAT_PFX_LOCK 4 /* 0xF0 */
2558 +#define INAT_PFX_CS 5 /* 0x2E */
2559 +#define INAT_PFX_DS 6 /* 0x3E */
2560 +#define INAT_PFX_ES 7 /* 0x26 */
2561 +#define INAT_PFX_FS 8 /* 0x64 */
2562 +#define INAT_PFX_GS 9 /* 0x65 */
2563 +#define INAT_PFX_SS 10 /* 0x36 */
2564 +#define INAT_PFX_ADDRSZ 11 /* 0x67 */
2565 +/* x86-64 REX prefix */
2566 +#define INAT_PFX_REX 12 /* 0x4X */
2567 +/* AVX VEX prefixes */
2568 +#define INAT_PFX_VEX2 13 /* 2-bytes VEX prefix */
2569 +#define INAT_PFX_VEX3 14 /* 3-bytes VEX prefix */
2570 +#define INAT_PFX_EVEX 15 /* EVEX prefix */
2571 +
2572 +#define INAT_LSTPFX_MAX 3
2573 +#define INAT_LGCPFX_MAX 11
2574 +
2575 +/* Immediate size */
2576 +#define INAT_IMM_BYTE 1
2577 +#define INAT_IMM_WORD 2
2578 +#define INAT_IMM_DWORD 3
2579 +#define INAT_IMM_QWORD 4
2580 +#define INAT_IMM_PTR 5
2581 +#define INAT_IMM_VWORD32 6
2582 +#define INAT_IMM_VWORD 7
2583 +
2584 +/* Legacy prefix */
2585 +#define INAT_PFX_OFFS 0
2586 +#define INAT_PFX_BITS 4
2587 +#define INAT_PFX_MAX ((1 << INAT_PFX_BITS) - 1)
2588 +#define INAT_PFX_MASK (INAT_PFX_MAX << INAT_PFX_OFFS)
2589 +/* Escape opcodes */
2590 +#define INAT_ESC_OFFS (INAT_PFX_OFFS + INAT_PFX_BITS)
2591 +#define INAT_ESC_BITS 2
2592 +#define INAT_ESC_MAX ((1 << INAT_ESC_BITS) - 1)
2593 +#define INAT_ESC_MASK (INAT_ESC_MAX << INAT_ESC_OFFS)
2594 +/* Group opcodes (1-16) */
2595 +#define INAT_GRP_OFFS (INAT_ESC_OFFS + INAT_ESC_BITS)
2596 +#define INAT_GRP_BITS 5
2597 +#define INAT_GRP_MAX ((1 << INAT_GRP_BITS) - 1)
2598 +#define INAT_GRP_MASK (INAT_GRP_MAX << INAT_GRP_OFFS)
2599 +/* Immediates */
2600 +#define INAT_IMM_OFFS (INAT_GRP_OFFS + INAT_GRP_BITS)
2601 +#define INAT_IMM_BITS 3
2602 +#define INAT_IMM_MASK (((1 << INAT_IMM_BITS) - 1) << INAT_IMM_OFFS)
2603 +/* Flags */
2604 +#define INAT_FLAG_OFFS (INAT_IMM_OFFS + INAT_IMM_BITS)
2605 +#define INAT_MODRM (1 << (INAT_FLAG_OFFS))
2606 +#define INAT_FORCE64 (1 << (INAT_FLAG_OFFS + 1))
2607 +#define INAT_SCNDIMM (1 << (INAT_FLAG_OFFS + 2))
2608 +#define INAT_MOFFSET (1 << (INAT_FLAG_OFFS + 3))
2609 +#define INAT_VARIANT (1 << (INAT_FLAG_OFFS + 4))
2610 +#define INAT_VEXOK (1 << (INAT_FLAG_OFFS + 5))
2611 +#define INAT_VEXONLY (1 << (INAT_FLAG_OFFS + 6))
2612 +#define INAT_EVEXONLY (1 << (INAT_FLAG_OFFS + 7))
2613 +/* Attribute making macros for attribute tables */
2614 +#define INAT_MAKE_PREFIX(pfx) (pfx << INAT_PFX_OFFS)
2615 +#define INAT_MAKE_ESCAPE(esc) (esc << INAT_ESC_OFFS)
2616 +#define INAT_MAKE_GROUP(grp) ((grp << INAT_GRP_OFFS) | INAT_MODRM)
2617 +#define INAT_MAKE_IMM(imm) (imm << INAT_IMM_OFFS)
2618 +
2619 +/* Attribute search APIs */
2620 +extern insn_attr_t inat_get_opcode_attribute(insn_byte_t opcode);
2621 +extern int inat_get_last_prefix_id(insn_byte_t last_pfx);
2622 +extern insn_attr_t inat_get_escape_attribute(insn_byte_t opcode,
2623 + int lpfx_id,
2624 + insn_attr_t esc_attr);
2625 +extern insn_attr_t inat_get_group_attribute(insn_byte_t modrm,
2626 + int lpfx_id,
2627 + insn_attr_t esc_attr);
2628 +extern insn_attr_t inat_get_avx_attribute(insn_byte_t opcode,
2629 + insn_byte_t vex_m,
2630 + insn_byte_t vex_pp);
2631 +
2632 +/* Attribute checking functions */
2633 +static inline int inat_is_legacy_prefix(insn_attr_t attr)
2634 +{
2635 + attr &= INAT_PFX_MASK;
2636 + return attr && attr <= INAT_LGCPFX_MAX;
2637 +}
2638 +
2639 +static inline int inat_is_address_size_prefix(insn_attr_t attr)
2640 +{
2641 + return (attr & INAT_PFX_MASK) == INAT_PFX_ADDRSZ;
2642 +}
2643 +
2644 +static inline int inat_is_operand_size_prefix(insn_attr_t attr)
2645 +{
2646 + return (attr & INAT_PFX_MASK) == INAT_PFX_OPNDSZ;
2647 +}
2648 +
2649 +static inline int inat_is_rex_prefix(insn_attr_t attr)
2650 +{
2651 + return (attr & INAT_PFX_MASK) == INAT_PFX_REX;
2652 +}
2653 +
2654 +static inline int inat_last_prefix_id(insn_attr_t attr)
2655 +{
2656 + if ((attr & INAT_PFX_MASK) > INAT_LSTPFX_MAX)
2657 + return 0;
2658 + else
2659 + return attr & INAT_PFX_MASK;
2660 +}
2661 +
2662 +static inline int inat_is_vex_prefix(insn_attr_t attr)
2663 +{
2664 + attr &= INAT_PFX_MASK;
2665 + return attr == INAT_PFX_VEX2 || attr == INAT_PFX_VEX3 ||
2666 + attr == INAT_PFX_EVEX;
2667 +}
2668 +
2669 +static inline int inat_is_evex_prefix(insn_attr_t attr)
2670 +{
2671 + return (attr & INAT_PFX_MASK) == INAT_PFX_EVEX;
2672 +}
2673 +
2674 +static inline int inat_is_vex3_prefix(insn_attr_t attr)
2675 +{
2676 + return (attr & INAT_PFX_MASK) == INAT_PFX_VEX3;
2677 +}
2678 +
2679 +static inline int inat_is_escape(insn_attr_t attr)
2680 +{
2681 + return attr & INAT_ESC_MASK;
2682 +}
2683 +
2684 +static inline int inat_escape_id(insn_attr_t attr)
2685 +{
2686 + return (attr & INAT_ESC_MASK) >> INAT_ESC_OFFS;
2687 +}
2688 +
2689 +static inline int inat_is_group(insn_attr_t attr)
2690 +{
2691 + return attr & INAT_GRP_MASK;
2692 +}
2693 +
2694 +static inline int inat_group_id(insn_attr_t attr)
2695 +{
2696 + return (attr & INAT_GRP_MASK) >> INAT_GRP_OFFS;
2697 +}
2698 +
2699 +static inline int inat_group_common_attribute(insn_attr_t attr)
2700 +{
2701 + return attr & ~INAT_GRP_MASK;
2702 +}
2703 +
2704 +static inline int inat_has_immediate(insn_attr_t attr)
2705 +{
2706 + return attr & INAT_IMM_MASK;
2707 +}
2708 +
2709 +static inline int inat_immediate_size(insn_attr_t attr)
2710 +{
2711 + return (attr & INAT_IMM_MASK) >> INAT_IMM_OFFS;
2712 +}
2713 +
2714 +static inline int inat_has_modrm(insn_attr_t attr)
2715 +{
2716 + return attr & INAT_MODRM;
2717 +}
2718 +
2719 +static inline int inat_is_force64(insn_attr_t attr)
2720 +{
2721 + return attr & INAT_FORCE64;
2722 +}
2723 +
2724 +static inline int inat_has_second_immediate(insn_attr_t attr)
2725 +{
2726 + return attr & INAT_SCNDIMM;
2727 +}
2728 +
2729 +static inline int inat_has_moffset(insn_attr_t attr)
2730 +{
2731 + return attr & INAT_MOFFSET;
2732 +}
2733 +
2734 +static inline int inat_has_variant(insn_attr_t attr)
2735 +{
2736 + return attr & INAT_VARIANT;
2737 +}
2738 +
2739 +static inline int inat_accept_vex(insn_attr_t attr)
2740 +{
2741 + return attr & INAT_VEXOK;
2742 +}
2743 +
2744 +static inline int inat_must_vex(insn_attr_t attr)
2745 +{
2746 + return attr & (INAT_VEXONLY | INAT_EVEXONLY);
2747 +}
2748 +
2749 +static inline int inat_must_evex(insn_attr_t attr)
2750 +{
2751 + return attr & INAT_EVEXONLY;
2752 +}
2753 +#endif
2754 diff --git a/tools/objtool/arch/x86/include/asm/inat_types.h b/tools/objtool/arch/x86/include/asm/inat_types.h
2755 new file mode 100644
2756 index 000000000000..cb3c20ce39cf
2757 --- /dev/null
2758 +++ b/tools/objtool/arch/x86/include/asm/inat_types.h
2759 @@ -0,0 +1,29 @@
2760 +#ifndef _ASM_X86_INAT_TYPES_H
2761 +#define _ASM_X86_INAT_TYPES_H
2762 +/*
2763 + * x86 instruction attributes
2764 + *
2765 + * Written by Masami Hiramatsu <mhiramat@redhat.com>
2766 + *
2767 + * This program is free software; you can redistribute it and/or modify
2768 + * it under the terms of the GNU General Public License as published by
2769 + * the Free Software Foundation; either version 2 of the License, or
2770 + * (at your option) any later version.
2771 + *
2772 + * This program is distributed in the hope that it will be useful,
2773 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
2774 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2775 + * GNU General Public License for more details.
2776 + *
2777 + * You should have received a copy of the GNU General Public License
2778 + * along with this program; if not, write to the Free Software
2779 + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
2780 + *
2781 + */
2782 +
2783 +/* Instruction attributes */
2784 +typedef unsigned int insn_attr_t;
2785 +typedef unsigned char insn_byte_t;
2786 +typedef signed int insn_value_t;
2787 +
2788 +#endif
2789 diff --git a/tools/objtool/arch/x86/include/asm/insn.h b/tools/objtool/arch/x86/include/asm/insn.h
2790 new file mode 100644
2791 index 000000000000..b3e32b010ab1
2792 --- /dev/null
2793 +++ b/tools/objtool/arch/x86/include/asm/insn.h
2794 @@ -0,0 +1,211 @@
2795 +#ifndef _ASM_X86_INSN_H
2796 +#define _ASM_X86_INSN_H
2797 +/*
2798 + * x86 instruction analysis
2799 + *
2800 + * This program is free software; you can redistribute it and/or modify
2801 + * it under the terms of the GNU General Public License as published by
2802 + * the Free Software Foundation; either version 2 of the License, or
2803 + * (at your option) any later version.
2804 + *
2805 + * This program is distributed in the hope that it will be useful,
2806 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
2807 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2808 + * GNU General Public License for more details.
2809 + *
2810 + * You should have received a copy of the GNU General Public License
2811 + * along with this program; if not, write to the Free Software
2812 + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
2813 + *
2814 + * Copyright (C) IBM Corporation, 2009
2815 + */
2816 +
2817 +/* insn_attr_t is defined in inat.h */
2818 +#include <asm/inat.h>
2819 +
2820 +struct insn_field {
2821 + union {
2822 + insn_value_t value;
2823 + insn_byte_t bytes[4];
2824 + };
2825 + /* !0 if we've run insn_get_xxx() for this field */
2826 + unsigned char got;
2827 + unsigned char nbytes;
2828 +};
2829 +
2830 +struct insn {
2831 + struct insn_field prefixes; /*
2832 + * Prefixes
2833 + * prefixes.bytes[3]: last prefix
2834 + */
2835 + struct insn_field rex_prefix; /* REX prefix */
2836 + struct insn_field vex_prefix; /* VEX prefix */
2837 + struct insn_field opcode; /*
2838 + * opcode.bytes[0]: opcode1
2839 + * opcode.bytes[1]: opcode2
2840 + * opcode.bytes[2]: opcode3
2841 + */
2842 + struct insn_field modrm;
2843 + struct insn_field sib;
2844 + struct insn_field displacement;
2845 + union {
2846 + struct insn_field immediate;
2847 + struct insn_field moffset1; /* for 64bit MOV */
2848 + struct insn_field immediate1; /* for 64bit imm or off16/32 */
2849 + };
2850 + union {
2851 + struct insn_field moffset2; /* for 64bit MOV */
2852 + struct insn_field immediate2; /* for 64bit imm or seg16 */
2853 + };
2854 +
2855 + insn_attr_t attr;
2856 + unsigned char opnd_bytes;
2857 + unsigned char addr_bytes;
2858 + unsigned char length;
2859 + unsigned char x86_64;
2860 +
2861 + const insn_byte_t *kaddr; /* kernel address of insn to analyze */
2862 + const insn_byte_t *end_kaddr; /* kernel address of last insn in buffer */
2863 + const insn_byte_t *next_byte;
2864 +};
2865 +
2866 +#define MAX_INSN_SIZE 15
2867 +
2868 +#define X86_MODRM_MOD(modrm) (((modrm) & 0xc0) >> 6)
2869 +#define X86_MODRM_REG(modrm) (((modrm) & 0x38) >> 3)
2870 +#define X86_MODRM_RM(modrm) ((modrm) & 0x07)
2871 +
2872 +#define X86_SIB_SCALE(sib) (((sib) & 0xc0) >> 6)
2873 +#define X86_SIB_INDEX(sib) (((sib) & 0x38) >> 3)
2874 +#define X86_SIB_BASE(sib) ((sib) & 0x07)
2875 +
2876 +#define X86_REX_W(rex) ((rex) & 8)
2877 +#define X86_REX_R(rex) ((rex) & 4)
2878 +#define X86_REX_X(rex) ((rex) & 2)
2879 +#define X86_REX_B(rex) ((rex) & 1)
2880 +
2881 +/* VEX bit flags */
2882 +#define X86_VEX_W(vex) ((vex) & 0x80) /* VEX3 Byte2 */
2883 +#define X86_VEX_R(vex) ((vex) & 0x80) /* VEX2/3 Byte1 */
2884 +#define X86_VEX_X(vex) ((vex) & 0x40) /* VEX3 Byte1 */
2885 +#define X86_VEX_B(vex) ((vex) & 0x20) /* VEX3 Byte1 */
2886 +#define X86_VEX_L(vex) ((vex) & 0x04) /* VEX3 Byte2, VEX2 Byte1 */
2887 +/* VEX bit fields */
2888 +#define X86_EVEX_M(vex) ((vex) & 0x03) /* EVEX Byte1 */
2889 +#define X86_VEX3_M(vex) ((vex) & 0x1f) /* VEX3 Byte1 */
2890 +#define X86_VEX2_M 1 /* VEX2.M always 1 */
2891 +#define X86_VEX_V(vex) (((vex) & 0x78) >> 3) /* VEX3 Byte2, VEX2 Byte1 */
2892 +#define X86_VEX_P(vex) ((vex) & 0x03) /* VEX3 Byte2, VEX2 Byte1 */
2893 +#define X86_VEX_M_MAX 0x1f /* VEX3.M Maximum value */
2894 +
2895 +extern void insn_init(struct insn *insn, const void *kaddr, int buf_len, int x86_64);
2896 +extern void insn_get_prefixes(struct insn *insn);
2897 +extern void insn_get_opcode(struct insn *insn);
2898 +extern void insn_get_modrm(struct insn *insn);
2899 +extern void insn_get_sib(struct insn *insn);
2900 +extern void insn_get_displacement(struct insn *insn);
2901 +extern void insn_get_immediate(struct insn *insn);
2902 +extern void insn_get_length(struct insn *insn);
2903 +
2904 +/* Attribute will be determined after getting ModRM (for opcode groups) */
2905 +static inline void insn_get_attribute(struct insn *insn)
2906 +{
2907 + insn_get_modrm(insn);
2908 +}
2909 +
2910 +/* Instruction uses RIP-relative addressing */
2911 +extern int insn_rip_relative(struct insn *insn);
2912 +
2913 +/* Init insn for kernel text */
2914 +static inline void kernel_insn_init(struct insn *insn,
2915 + const void *kaddr, int buf_len)
2916 +{
2917 +#ifdef CONFIG_X86_64
2918 + insn_init(insn, kaddr, buf_len, 1);
2919 +#else /* CONFIG_X86_32 */
2920 + insn_init(insn, kaddr, buf_len, 0);
2921 +#endif
2922 +}
2923 +
2924 +static inline int insn_is_avx(struct insn *insn)
2925 +{
2926 + if (!insn->prefixes.got)
2927 + insn_get_prefixes(insn);
2928 + return (insn->vex_prefix.value != 0);
2929 +}
2930 +
2931 +static inline int insn_is_evex(struct insn *insn)
2932 +{
2933 + if (!insn->prefixes.got)
2934 + insn_get_prefixes(insn);
2935 + return (insn->vex_prefix.nbytes == 4);
2936 +}
2937 +
2938 +/* Ensure this instruction is decoded completely */
2939 +static inline int insn_complete(struct insn *insn)
2940 +{
2941 + return insn->opcode.got && insn->modrm.got && insn->sib.got &&
2942 + insn->displacement.got && insn->immediate.got;
2943 +}
2944 +
2945 +static inline insn_byte_t insn_vex_m_bits(struct insn *insn)
2946 +{
2947 + if (insn->vex_prefix.nbytes == 2) /* 2 bytes VEX */
2948 + return X86_VEX2_M;
2949 + else if (insn->vex_prefix.nbytes == 3) /* 3 bytes VEX */
2950 + return X86_VEX3_M(insn->vex_prefix.bytes[1]);
2951 + else /* EVEX */
2952 + return X86_EVEX_M(insn->vex_prefix.bytes[1]);
2953 +}
2954 +
2955 +static inline insn_byte_t insn_vex_p_bits(struct insn *insn)
2956 +{
2957 + if (insn->vex_prefix.nbytes == 2) /* 2 bytes VEX */
2958 + return X86_VEX_P(insn->vex_prefix.bytes[1]);
2959 + else
2960 + return X86_VEX_P(insn->vex_prefix.bytes[2]);
2961 +}
2962 +
2963 +/* Get the last prefix id from last prefix or VEX prefix */
2964 +static inline int insn_last_prefix_id(struct insn *insn)
2965 +{
2966 + if (insn_is_avx(insn))
2967 + return insn_vex_p_bits(insn); /* VEX_p is a SIMD prefix id */
2968 +
2969 + if (insn->prefixes.bytes[3])
2970 + return inat_get_last_prefix_id(insn->prefixes.bytes[3]);
2971 +
2972 + return 0;
2973 +}
2974 +
2975 +/* Offset of each field from kaddr */
2976 +static inline int insn_offset_rex_prefix(struct insn *insn)
2977 +{
2978 + return insn->prefixes.nbytes;
2979 +}
2980 +static inline int insn_offset_vex_prefix(struct insn *insn)
2981 +{
2982 + return insn_offset_rex_prefix(insn) + insn->rex_prefix.nbytes;
2983 +}
2984 +static inline int insn_offset_opcode(struct insn *insn)
2985 +{
2986 + return insn_offset_vex_prefix(insn) + insn->vex_prefix.nbytes;
2987 +}
2988 +static inline int insn_offset_modrm(struct insn *insn)
2989 +{
2990 + return insn_offset_opcode(insn) + insn->opcode.nbytes;
2991 +}
2992 +static inline int insn_offset_sib(struct insn *insn)
2993 +{
2994 + return insn_offset_modrm(insn) + insn->modrm.nbytes;
2995 +}
2996 +static inline int insn_offset_displacement(struct insn *insn)
2997 +{
2998 + return insn_offset_sib(insn) + insn->sib.nbytes;
2999 +}
3000 +static inline int insn_offset_immediate(struct insn *insn)
3001 +{
3002 + return insn_offset_displacement(insn) + insn->displacement.nbytes;
3003 +}
3004 +
3005 +#endif /* _ASM_X86_INSN_H */
3006 diff --git a/tools/objtool/arch/x86/include/asm/orc_types.h b/tools/objtool/arch/x86/include/asm/orc_types.h
3007 new file mode 100644
3008 index 000000000000..7dc777a6cb40
3009 --- /dev/null
3010 +++ b/tools/objtool/arch/x86/include/asm/orc_types.h
3011 @@ -0,0 +1,107 @@
3012 +/*
3013 + * Copyright (C) 2017 Josh Poimboeuf <jpoimboe@redhat.com>
3014 + *
3015 + * This program is free software; you can redistribute it and/or
3016 + * modify it under the terms of the GNU General Public License
3017 + * as published by the Free Software Foundation; either version 2
3018 + * of the License, or (at your option) any later version.
3019 + *
3020 + * This program is distributed in the hope that it will be useful,
3021 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
3022 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3023 + * GNU General Public License for more details.
3024 + *
3025 + * You should have received a copy of the GNU General Public License
3026 + * along with this program; if not, see <http://www.gnu.org/licenses/>.
3027 + */
3028 +
3029 +#ifndef _ORC_TYPES_H
3030 +#define _ORC_TYPES_H
3031 +
3032 +#include <linux/types.h>
3033 +#include <linux/compiler.h>
3034 +
3035 +/*
3036 + * The ORC_REG_* registers are base registers which are used to find other
3037 + * registers on the stack.
3038 + *
3039 + * ORC_REG_PREV_SP, also known as DWARF Call Frame Address (CFA), is the
3040 + * address of the previous frame: the caller's SP before it called the current
3041 + * function.
3042 + *
3043 + * ORC_REG_UNDEFINED means the corresponding register's value didn't change in
3044 + * the current frame.
3045 + *
3046 + * The most commonly used base registers are SP and BP -- which the previous SP
3047 + * is usually based on -- and PREV_SP and UNDEFINED -- which the previous BP is
3048 + * usually based on.
3049 + *
3050 + * The rest of the base registers are needed for special cases like entry code
3051 + * and GCC realigned stacks.
3052 + */
3053 +#define ORC_REG_UNDEFINED 0
3054 +#define ORC_REG_PREV_SP 1
3055 +#define ORC_REG_DX 2
3056 +#define ORC_REG_DI 3
3057 +#define ORC_REG_BP 4
3058 +#define ORC_REG_SP 5
3059 +#define ORC_REG_R10 6
3060 +#define ORC_REG_R13 7
3061 +#define ORC_REG_BP_INDIRECT 8
3062 +#define ORC_REG_SP_INDIRECT 9
3063 +#define ORC_REG_MAX 15
3064 +
3065 +/*
3066 + * ORC_TYPE_CALL: Indicates that sp_reg+sp_offset resolves to PREV_SP (the
3067 + * caller's SP right before it made the call). Used for all callable
3068 + * functions, i.e. all C code and all callable asm functions.
3069 + *
3070 + * ORC_TYPE_REGS: Used in entry code to indicate that sp_reg+sp_offset points
3071 + * to a fully populated pt_regs from a syscall, interrupt, or exception.
3072 + *
3073 + * ORC_TYPE_REGS_IRET: Used in entry code to indicate that sp_reg+sp_offset
3074 + * points to the iret return frame.
3075 + *
3076 + * The UNWIND_HINT macros are used only for the unwind_hint struct. They
3077 + * aren't used in struct orc_entry due to size and complexity constraints.
3078 + * Objtool converts them to real types when it converts the hints to orc
3079 + * entries.
3080 + */
3081 +#define ORC_TYPE_CALL 0
3082 +#define ORC_TYPE_REGS 1
3083 +#define ORC_TYPE_REGS_IRET 2
3084 +#define UNWIND_HINT_TYPE_SAVE 3
3085 +#define UNWIND_HINT_TYPE_RESTORE 4
3086 +
3087 +#ifndef __ASSEMBLY__
3088 +/*
3089 + * This struct is more or less a vastly simplified version of the DWARF Call
3090 + * Frame Information standard. It contains only the necessary parts of DWARF
3091 + * CFI, simplified for ease of access by the in-kernel unwinder. It tells the
3092 + * unwinder how to find the previous SP and BP (and sometimes entry regs) on
3093 + * the stack for a given code address. Each instance of the struct corresponds
3094 + * to one or more code locations.
3095 + */
3096 +struct orc_entry {
3097 + s16 sp_offset;
3098 + s16 bp_offset;
3099 + unsigned sp_reg:4;
3100 + unsigned bp_reg:4;
3101 + unsigned type:2;
3102 +};
3103 +
3104 +/*
3105 + * This struct is used by asm and inline asm code to manually annotate the
3106 + * location of registers on the stack for the ORC unwinder.
3107 + *
3108 + * Type can be either ORC_TYPE_* or UNWIND_HINT_TYPE_*.
3109 + */
3110 +struct unwind_hint {
3111 + u32 ip;
3112 + s16 sp_offset;
3113 + u8 sp_reg;
3114 + u8 type;
3115 +};
3116 +#endif /* __ASSEMBLY__ */
3117 +
3118 +#endif /* _ORC_TYPES_H */
3119 diff --git a/tools/objtool/arch/x86/insn/gen-insn-attr-x86.awk b/tools/objtool/arch/x86/insn/gen-insn-attr-x86.awk
3120 deleted file mode 100644
3121 index a3d2c62fd805..000000000000
3122 --- a/tools/objtool/arch/x86/insn/gen-insn-attr-x86.awk
3123 +++ /dev/null
3124 @@ -1,392 +0,0 @@
3125 -#!/bin/awk -f
3126 -# gen-insn-attr-x86.awk: Instruction attribute table generator
3127 -# Written by Masami Hiramatsu <mhiramat@redhat.com>
3128 -#
3129 -# Usage: awk -f gen-insn-attr-x86.awk x86-opcode-map.txt > inat-tables.c
3130 -
3131 -# Awk implementation sanity check
3132 -function check_awk_implement() {
3133 - if (sprintf("%x", 0) != "0")
3134 - return "Your awk has a printf-format problem."
3135 - return ""
3136 -}
3137 -
3138 -# Clear working vars
3139 -function clear_vars() {
3140 - delete table
3141 - delete lptable2
3142 - delete lptable1
3143 - delete lptable3
3144 - eid = -1 # escape id
3145 - gid = -1 # group id
3146 - aid = -1 # AVX id
3147 - tname = ""
3148 -}
3149 -
3150 -BEGIN {
3151 - # Implementation error checking
3152 - awkchecked = check_awk_implement()
3153 - if (awkchecked != "") {
3154 - print "Error: " awkchecked > "/dev/stderr"
3155 - print "Please try to use gawk." > "/dev/stderr"
3156 - exit 1
3157 - }
3158 -
3159 - # Setup generating tables
3160 - print "/* x86 opcode map generated from x86-opcode-map.txt */"
3161 - print "/* Do not change this code. */\n"
3162 - ggid = 1
3163 - geid = 1
3164 - gaid = 0
3165 - delete etable
3166 - delete gtable
3167 - delete atable
3168 -
3169 - opnd_expr = "^[A-Za-z/]"
3170 - ext_expr = "^\\("
3171 - sep_expr = "^\\|$"
3172 - group_expr = "^Grp[0-9A-Za-z]+"
3173 -
3174 - imm_expr = "^[IJAOL][a-z]"
3175 - imm_flag["Ib"] = "INAT_MAKE_IMM(INAT_IMM_BYTE)"
3176 - imm_flag["Jb"] = "INAT_MAKE_IMM(INAT_IMM_BYTE)"
3177 - imm_flag["Iw"] = "INAT_MAKE_IMM(INAT_IMM_WORD)"
3178 - imm_flag["Id"] = "INAT_MAKE_IMM(INAT_IMM_DWORD)"
3179 - imm_flag["Iq"] = "INAT_MAKE_IMM(INAT_IMM_QWORD)"
3180 - imm_flag["Ap"] = "INAT_MAKE_IMM(INAT_IMM_PTR)"
3181 - imm_flag["Iz"] = "INAT_MAKE_IMM(INAT_IMM_VWORD32)"
3182 - imm_flag["Jz"] = "INAT_MAKE_IMM(INAT_IMM_VWORD32)"
3183 - imm_flag["Iv"] = "INAT_MAKE_IMM(INAT_IMM_VWORD)"
3184 - imm_flag["Ob"] = "INAT_MOFFSET"
3185 - imm_flag["Ov"] = "INAT_MOFFSET"
3186 - imm_flag["Lx"] = "INAT_MAKE_IMM(INAT_IMM_BYTE)"
3187 -
3188 - modrm_expr = "^([CDEGMNPQRSUVW/][a-z]+|NTA|T[012])"
3189 - force64_expr = "\\([df]64\\)"
3190 - rex_expr = "^REX(\\.[XRWB]+)*"
3191 - fpu_expr = "^ESC" # TODO
3192 -
3193 - lprefix1_expr = "\\((66|!F3)\\)"
3194 - lprefix2_expr = "\\(F3\\)"
3195 - lprefix3_expr = "\\((F2|!F3|66\\&F2)\\)"
3196 - lprefix_expr = "\\((66|F2|F3)\\)"
3197 - max_lprefix = 4
3198 -
3199 - # All opcodes starting with lower-case 'v', 'k' or with (v1) superscript
3200 - # accepts VEX prefix
3201 - vexok_opcode_expr = "^[vk].*"
3202 - vexok_expr = "\\(v1\\)"
3203 - # All opcodes with (v) superscript supports *only* VEX prefix
3204 - vexonly_expr = "\\(v\\)"
3205 - # All opcodes with (ev) superscript supports *only* EVEX prefix
3206 - evexonly_expr = "\\(ev\\)"
3207 -
3208 - prefix_expr = "\\(Prefix\\)"
3209 - prefix_num["Operand-Size"] = "INAT_PFX_OPNDSZ"
3210 - prefix_num["REPNE"] = "INAT_PFX_REPNE"
3211 - prefix_num["REP/REPE"] = "INAT_PFX_REPE"
3212 - prefix_num["XACQUIRE"] = "INAT_PFX_REPNE"
3213 - prefix_num["XRELEASE"] = "INAT_PFX_REPE"
3214 - prefix_num["LOCK"] = "INAT_PFX_LOCK"
3215 - prefix_num["SEG=CS"] = "INAT_PFX_CS"
3216 - prefix_num["SEG=DS"] = "INAT_PFX_DS"
3217 - prefix_num["SEG=ES"] = "INAT_PFX_ES"
3218 - prefix_num["SEG=FS"] = "INAT_PFX_FS"
3219 - prefix_num["SEG=GS"] = "INAT_PFX_GS"
3220 - prefix_num["SEG=SS"] = "INAT_PFX_SS"
3221 - prefix_num["Address-Size"] = "INAT_PFX_ADDRSZ"
3222 - prefix_num["VEX+1byte"] = "INAT_PFX_VEX2"
3223 - prefix_num["VEX+2byte"] = "INAT_PFX_VEX3"
3224 - prefix_num["EVEX"] = "INAT_PFX_EVEX"
3225 -
3226 - clear_vars()
3227 -}
3228 -
3229 -function semantic_error(msg) {
3230 - print "Semantic error at " NR ": " msg > "/dev/stderr"
3231 - exit 1
3232 -}
3233 -
3234 -function debug(msg) {
3235 - print "DEBUG: " msg
3236 -}
3237 -
3238 -function array_size(arr, i,c) {
3239 - c = 0
3240 - for (i in arr)
3241 - c++
3242 - return c
3243 -}
3244 -
3245 -/^Table:/ {
3246 - print "/* " $0 " */"
3247 - if (tname != "")
3248 - semantic_error("Hit Table: before EndTable:.");
3249 -}
3250 -
3251 -/^Referrer:/ {
3252 - if (NF != 1) {
3253 - # escape opcode table
3254 - ref = ""
3255 - for (i = 2; i <= NF; i++)
3256 - ref = ref $i
3257 - eid = escape[ref]
3258 - tname = sprintf("inat_escape_table_%d", eid)
3259 - }
3260 -}
3261 -
3262 -/^AVXcode:/ {
3263 - if (NF != 1) {
3264 - # AVX/escape opcode table
3265 - aid = $2
3266 - if (gaid <= aid)
3267 - gaid = aid + 1
3268 - if (tname == "") # AVX only opcode table
3269 - tname = sprintf("inat_avx_table_%d", $2)
3270 - }
3271 - if (aid == -1 && eid == -1) # primary opcode table
3272 - tname = "inat_primary_table"
3273 -}
3274 -
3275 -/^GrpTable:/ {
3276 - print "/* " $0 " */"
3277 - if (!($2 in group))
3278 - semantic_error("No group: " $2 )
3279 - gid = group[$2]
3280 - tname = "inat_group_table_" gid
3281 -}
3282 -
3283 -function print_table(tbl,name,fmt,n)
3284 -{
3285 - print "const insn_attr_t " name " = {"
3286 - for (i = 0; i < n; i++) {
3287 - id = sprintf(fmt, i)
3288 - if (tbl[id])
3289 - print " [" id "] = " tbl[id] ","
3290 - }
3291 - print "};"
3292 -}
3293 -
3294 -/^EndTable/ {
3295 - if (gid != -1) {
3296 - # print group tables
3297 - if (array_size(table) != 0) {
3298 - print_table(table, tname "[INAT_GROUP_TABLE_SIZE]",
3299 - "0x%x", 8)
3300 - gtable[gid,0] = tname
3301 - }
3302 - if (array_size(lptable1) != 0) {
3303 - print_table(lptable1, tname "_1[INAT_GROUP_TABLE_SIZE]",
3304 - "0x%x", 8)
3305 - gtable[gid,1] = tname "_1"
3306 - }
3307 - if (array_size(lptable2) != 0) {
3308 - print_table(lptable2, tname "_2[INAT_GROUP_TABLE_SIZE]",
3309 - "0x%x", 8)
3310 - gtable[gid,2] = tname "_2"
3311 - }
3312 - if (array_size(lptable3) != 0) {
3313 - print_table(lptable3, tname "_3[INAT_GROUP_TABLE_SIZE]",
3314 - "0x%x", 8)
3315 - gtable[gid,3] = tname "_3"
3316 - }
3317 - } else {
3318 - # print primary/escaped tables
3319 - if (array_size(table) != 0) {
3320 - print_table(table, tname "[INAT_OPCODE_TABLE_SIZE]",
3321 - "0x%02x", 256)
3322 - etable[eid,0] = tname
3323 - if (aid >= 0)
3324 - atable[aid,0] = tname
3325 - }
3326 - if (array_size(lptable1) != 0) {
3327 - print_table(lptable1,tname "_1[INAT_OPCODE_TABLE_SIZE]",
3328 - "0x%02x", 256)
3329 - etable[eid,1] = tname "_1"
3330 - if (aid >= 0)
3331 - atable[aid,1] = tname "_1"
3332 - }
3333 - if (array_size(lptable2) != 0) {
3334 - print_table(lptable2,tname "_2[INAT_OPCODE_TABLE_SIZE]",
3335 - "0x%02x", 256)
3336 - etable[eid,2] = tname "_2"
3337 - if (aid >= 0)
3338 - atable[aid,2] = tname "_2"
3339 - }
3340 - if (array_size(lptable3) != 0) {
3341 - print_table(lptable3,tname "_3[INAT_OPCODE_TABLE_SIZE]",
3342 - "0x%02x", 256)
3343 - etable[eid,3] = tname "_3"
3344 - if (aid >= 0)
3345 - atable[aid,3] = tname "_3"
3346 - }
3347 - }
3348 - print ""
3349 - clear_vars()
3350 -}
3351 -
3352 -function add_flags(old,new) {
3353 - if (old && new)
3354 - return old " | " new
3355 - else if (old)
3356 - return old
3357 - else
3358 - return new
3359 -}
3360 -
3361 -# convert operands to flags.
3362 -function convert_operands(count,opnd, i,j,imm,mod)
3363 -{
3364 - imm = null
3365 - mod = null
3366 - for (j = 1; j <= count; j++) {
3367 - i = opnd[j]
3368 - if (match(i, imm_expr) == 1) {
3369 - if (!imm_flag[i])
3370 - semantic_error("Unknown imm opnd: " i)
3371 - if (imm) {
3372 - if (i != "Ib")
3373 - semantic_error("Second IMM error")
3374 - imm = add_flags(imm, "INAT_SCNDIMM")
3375 - } else
3376 - imm = imm_flag[i]
3377 - } else if (match(i, modrm_expr))
3378 - mod = "INAT_MODRM"
3379 - }
3380 - return add_flags(imm, mod)
3381 -}
3382 -
3383 -/^[0-9a-f]+\:/ {
3384 - if (NR == 1)
3385 - next
3386 - # get index
3387 - idx = "0x" substr($1, 1, index($1,":") - 1)
3388 - if (idx in table)
3389 - semantic_error("Redefine " idx " in " tname)
3390 -
3391 - # check if escaped opcode
3392 - if ("escape" == $2) {
3393 - if ($3 != "#")
3394 - semantic_error("No escaped name")
3395 - ref = ""
3396 - for (i = 4; i <= NF; i++)
3397 - ref = ref $i
3398 - if (ref in escape)
3399 - semantic_error("Redefine escape (" ref ")")
3400 - escape[ref] = geid
3401 - geid++
3402 - table[idx] = "INAT_MAKE_ESCAPE(" escape[ref] ")"
3403 - next
3404 - }
3405 -
3406 - variant = null
3407 - # converts
3408 - i = 2
3409 - while (i <= NF) {
3410 - opcode = $(i++)
3411 - delete opnds
3412 - ext = null
3413 - flags = null
3414 - opnd = null
3415 - # parse one opcode
3416 - if (match($i, opnd_expr)) {
3417 - opnd = $i
3418 - count = split($(i++), opnds, ",")
3419 - flags = convert_operands(count, opnds)
3420 - }
3421 - if (match($i, ext_expr))
3422 - ext = $(i++)
3423 - if (match($i, sep_expr))
3424 - i++
3425 - else if (i < NF)
3426 - semantic_error($i " is not a separator")
3427 -
3428 - # check if group opcode
3429 - if (match(opcode, group_expr)) {
3430 - if (!(opcode in group)) {
3431 - group[opcode] = ggid
3432 - ggid++
3433 - }
3434 - flags = add_flags(flags, "INAT_MAKE_GROUP(" group[opcode] ")")
3435 - }
3436 - # check force(or default) 64bit
3437 - if (match(ext, force64_expr))
3438 - flags = add_flags(flags, "INAT_FORCE64")
3439 -
3440 - # check REX prefix
3441 - if (match(opcode, rex_expr))
3442 - flags = add_flags(flags, "INAT_MAKE_PREFIX(INAT_PFX_REX)")
3443 -
3444 - # check coprocessor escape : TODO
3445 - if (match(opcode, fpu_expr))
3446 - flags = add_flags(flags, "INAT_MODRM")
3447 -
3448 - # check VEX codes
3449 - if (match(ext, evexonly_expr))
3450 - flags = add_flags(flags, "INAT_VEXOK | INAT_EVEXONLY")
3451 - else if (match(ext, vexonly_expr))
3452 - flags = add_flags(flags, "INAT_VEXOK | INAT_VEXONLY")
3453 - else if (match(ext, vexok_expr) || match(opcode, vexok_opcode_expr))
3454 - flags = add_flags(flags, "INAT_VEXOK")
3455 -
3456 - # check prefixes
3457 - if (match(ext, prefix_expr)) {
3458 - if (!prefix_num[opcode])
3459 - semantic_error("Unknown prefix: " opcode)
3460 - flags = add_flags(flags, "INAT_MAKE_PREFIX(" prefix_num[opcode] ")")
3461 - }
3462 - if (length(flags) == 0)
3463 - continue
3464 - # check if last prefix
3465 - if (match(ext, lprefix1_expr)) {
3466 - lptable1[idx] = add_flags(lptable1[idx],flags)
3467 - variant = "INAT_VARIANT"
3468 - }
3469 - if (match(ext, lprefix2_expr)) {
3470 - lptable2[idx] = add_flags(lptable2[idx],flags)
3471 - variant = "INAT_VARIANT"
3472 - }
3473 - if (match(ext, lprefix3_expr)) {
3474 - lptable3[idx] = add_flags(lptable3[idx],flags)
3475 - variant = "INAT_VARIANT"
3476 - }
3477 - if (!match(ext, lprefix_expr)){
3478 - table[idx] = add_flags(table[idx],flags)
3479 - }
3480 - }
3481 - if (variant)
3482 - table[idx] = add_flags(table[idx],variant)
3483 -}
3484 -
3485 -END {
3486 - if (awkchecked != "")
3487 - exit 1
3488 - # print escape opcode map's array
3489 - print "/* Escape opcode map array */"
3490 - print "const insn_attr_t * const inat_escape_tables[INAT_ESC_MAX + 1]" \
3491 - "[INAT_LSTPFX_MAX + 1] = {"
3492 - for (i = 0; i < geid; i++)
3493 - for (j = 0; j < max_lprefix; j++)
3494 - if (etable[i,j])
3495 - print " ["i"]["j"] = "etable[i,j]","
3496 - print "};\n"
3497 - # print group opcode map's array
3498 - print "/* Group opcode map array */"
3499 - print "const insn_attr_t * const inat_group_tables[INAT_GRP_MAX + 1]"\
3500 - "[INAT_LSTPFX_MAX + 1] = {"
3501 - for (i = 0; i < ggid; i++)
3502 - for (j = 0; j < max_lprefix; j++)
3503 - if (gtable[i,j])
3504 - print " ["i"]["j"] = "gtable[i,j]","
3505 - print "};\n"
3506 - # print AVX opcode map's array
3507 - print "/* AVX opcode map array */"
3508 - print "const insn_attr_t * const inat_avx_tables[X86_VEX_M_MAX + 1]"\
3509 - "[INAT_LSTPFX_MAX + 1] = {"
3510 - for (i = 0; i < gaid; i++)
3511 - for (j = 0; j < max_lprefix; j++)
3512 - if (atable[i,j])
3513 - print " ["i"]["j"] = "atable[i,j]","
3514 - print "};"
3515 -}
3516 -
3517 diff --git a/tools/objtool/arch/x86/insn/inat.c b/tools/objtool/arch/x86/insn/inat.c
3518 deleted file mode 100644
3519 index e4bf28e6f4c7..000000000000
3520 --- a/tools/objtool/arch/x86/insn/inat.c
3521 +++ /dev/null
3522 @@ -1,97 +0,0 @@
3523 -/*
3524 - * x86 instruction attribute tables
3525 - *
3526 - * Written by Masami Hiramatsu <mhiramat@redhat.com>
3527 - *
3528 - * This program is free software; you can redistribute it and/or modify
3529 - * it under the terms of the GNU General Public License as published by
3530 - * the Free Software Foundation; either version 2 of the License, or
3531 - * (at your option) any later version.
3532 - *
3533 - * This program is distributed in the hope that it will be useful,
3534 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
3535 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3536 - * GNU General Public License for more details.
3537 - *
3538 - * You should have received a copy of the GNU General Public License
3539 - * along with this program; if not, write to the Free Software
3540 - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
3541 - *
3542 - */
3543 -#include "insn.h"
3544 -
3545 -/* Attribute tables are generated from opcode map */
3546 -#include "inat-tables.c"
3547 -
3548 -/* Attribute search APIs */
3549 -insn_attr_t inat_get_opcode_attribute(insn_byte_t opcode)
3550 -{
3551 - return inat_primary_table[opcode];
3552 -}
3553 -
3554 -int inat_get_last_prefix_id(insn_byte_t last_pfx)
3555 -{
3556 - insn_attr_t lpfx_attr;
3557 -
3558 - lpfx_attr = inat_get_opcode_attribute(last_pfx);
3559 - return inat_last_prefix_id(lpfx_attr);
3560 -}
3561 -
3562 -insn_attr_t inat_get_escape_attribute(insn_byte_t opcode, int lpfx_id,
3563 - insn_attr_t esc_attr)
3564 -{
3565 - const insn_attr_t *table;
3566 - int n;
3567 -
3568 - n = inat_escape_id(esc_attr);
3569 -
3570 - table = inat_escape_tables[n][0];
3571 - if (!table)
3572 - return 0;
3573 - if (inat_has_variant(table[opcode]) && lpfx_id) {
3574 - table = inat_escape_tables[n][lpfx_id];
3575 - if (!table)
3576 - return 0;
3577 - }
3578 - return table[opcode];
3579 -}
3580 -
3581 -insn_attr_t inat_get_group_attribute(insn_byte_t modrm, int lpfx_id,
3582 - insn_attr_t grp_attr)
3583 -{
3584 - const insn_attr_t *table;
3585 - int n;
3586 -
3587 - n = inat_group_id(grp_attr);
3588 -
3589 - table = inat_group_tables[n][0];
3590 - if (!table)
3591 - return inat_group_common_attribute(grp_attr);
3592 - if (inat_has_variant(table[X86_MODRM_REG(modrm)]) && lpfx_id) {
3593 - table = inat_group_tables[n][lpfx_id];
3594 - if (!table)
3595 - return inat_group_common_attribute(grp_attr);
3596 - }
3597 - return table[X86_MODRM_REG(modrm)] |
3598 - inat_group_common_attribute(grp_attr);
3599 -}
3600 -
3601 -insn_attr_t inat_get_avx_attribute(insn_byte_t opcode, insn_byte_t vex_m,
3602 - insn_byte_t vex_p)
3603 -{
3604 - const insn_attr_t *table;
3605 - if (vex_m > X86_VEX_M_MAX || vex_p > INAT_LSTPFX_MAX)
3606 - return 0;
3607 - /* At first, this checks the master table */
3608 - table = inat_avx_tables[vex_m][0];
3609 - if (!table)
3610 - return 0;
3611 - if (!inat_is_group(table[opcode]) && vex_p) {
3612 - /* If this is not a group, get attribute directly */
3613 - table = inat_avx_tables[vex_m][vex_p];
3614 - if (!table)
3615 - return 0;
3616 - }
3617 - return table[opcode];
3618 -}
3619 -
3620 diff --git a/tools/objtool/arch/x86/insn/inat.h b/tools/objtool/arch/x86/insn/inat.h
3621 deleted file mode 100644
3622 index 125ecd2a300d..000000000000
3623 --- a/tools/objtool/arch/x86/insn/inat.h
3624 +++ /dev/null
3625 @@ -1,234 +0,0 @@
3626 -#ifndef _ASM_X86_INAT_H
3627 -#define _ASM_X86_INAT_H
3628 -/*
3629 - * x86 instruction attributes
3630 - *
3631 - * Written by Masami Hiramatsu <mhiramat@redhat.com>
3632 - *
3633 - * This program is free software; you can redistribute it and/or modify
3634 - * it under the terms of the GNU General Public License as published by
3635 - * the Free Software Foundation; either version 2 of the License, or
3636 - * (at your option) any later version.
3637 - *
3638 - * This program is distributed in the hope that it will be useful,
3639 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
3640 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3641 - * GNU General Public License for more details.
3642 - *
3643 - * You should have received a copy of the GNU General Public License
3644 - * along with this program; if not, write to the Free Software
3645 - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
3646 - *
3647 - */
3648 -#include "inat_types.h"
3649 -
3650 -/*
3651 - * Internal bits. Don't use bitmasks directly, because these bits are
3652 - * unstable. You should use checking functions.
3653 - */
3654 -
3655 -#define INAT_OPCODE_TABLE_SIZE 256
3656 -#define INAT_GROUP_TABLE_SIZE 8
3657 -
3658 -/* Legacy last prefixes */
3659 -#define INAT_PFX_OPNDSZ 1 /* 0x66 */ /* LPFX1 */
3660 -#define INAT_PFX_REPE 2 /* 0xF3 */ /* LPFX2 */
3661 -#define INAT_PFX_REPNE 3 /* 0xF2 */ /* LPFX3 */
3662 -/* Other Legacy prefixes */
3663 -#define INAT_PFX_LOCK 4 /* 0xF0 */
3664 -#define INAT_PFX_CS 5 /* 0x2E */
3665 -#define INAT_PFX_DS 6 /* 0x3E */
3666 -#define INAT_PFX_ES 7 /* 0x26 */
3667 -#define INAT_PFX_FS 8 /* 0x64 */
3668 -#define INAT_PFX_GS 9 /* 0x65 */
3669 -#define INAT_PFX_SS 10 /* 0x36 */
3670 -#define INAT_PFX_ADDRSZ 11 /* 0x67 */
3671 -/* x86-64 REX prefix */
3672 -#define INAT_PFX_REX 12 /* 0x4X */
3673 -/* AVX VEX prefixes */
3674 -#define INAT_PFX_VEX2 13 /* 2-bytes VEX prefix */
3675 -#define INAT_PFX_VEX3 14 /* 3-bytes VEX prefix */
3676 -#define INAT_PFX_EVEX 15 /* EVEX prefix */
3677 -
3678 -#define INAT_LSTPFX_MAX 3
3679 -#define INAT_LGCPFX_MAX 11
3680 -
3681 -/* Immediate size */
3682 -#define INAT_IMM_BYTE 1
3683 -#define INAT_IMM_WORD 2
3684 -#define INAT_IMM_DWORD 3
3685 -#define INAT_IMM_QWORD 4
3686 -#define INAT_IMM_PTR 5
3687 -#define INAT_IMM_VWORD32 6
3688 -#define INAT_IMM_VWORD 7
3689 -
3690 -/* Legacy prefix */
3691 -#define INAT_PFX_OFFS 0
3692 -#define INAT_PFX_BITS 4
3693 -#define INAT_PFX_MAX ((1 << INAT_PFX_BITS) - 1)
3694 -#define INAT_PFX_MASK (INAT_PFX_MAX << INAT_PFX_OFFS)
3695 -/* Escape opcodes */
3696 -#define INAT_ESC_OFFS (INAT_PFX_OFFS + INAT_PFX_BITS)
3697 -#define INAT_ESC_BITS 2
3698 -#define INAT_ESC_MAX ((1 << INAT_ESC_BITS) - 1)
3699 -#define INAT_ESC_MASK (INAT_ESC_MAX << INAT_ESC_OFFS)
3700 -/* Group opcodes (1-16) */
3701 -#define INAT_GRP_OFFS (INAT_ESC_OFFS + INAT_ESC_BITS)
3702 -#define INAT_GRP_BITS 5
3703 -#define INAT_GRP_MAX ((1 << INAT_GRP_BITS) - 1)
3704 -#define INAT_GRP_MASK (INAT_GRP_MAX << INAT_GRP_OFFS)
3705 -/* Immediates */
3706 -#define INAT_IMM_OFFS (INAT_GRP_OFFS + INAT_GRP_BITS)
3707 -#define INAT_IMM_BITS 3
3708 -#define INAT_IMM_MASK (((1 << INAT_IMM_BITS) - 1) << INAT_IMM_OFFS)
3709 -/* Flags */
3710 -#define INAT_FLAG_OFFS (INAT_IMM_OFFS + INAT_IMM_BITS)
3711 -#define INAT_MODRM (1 << (INAT_FLAG_OFFS))
3712 -#define INAT_FORCE64 (1 << (INAT_FLAG_OFFS + 1))
3713 -#define INAT_SCNDIMM (1 << (INAT_FLAG_OFFS + 2))
3714 -#define INAT_MOFFSET (1 << (INAT_FLAG_OFFS + 3))
3715 -#define INAT_VARIANT (1 << (INAT_FLAG_OFFS + 4))
3716 -#define INAT_VEXOK (1 << (INAT_FLAG_OFFS + 5))
3717 -#define INAT_VEXONLY (1 << (INAT_FLAG_OFFS + 6))
3718 -#define INAT_EVEXONLY (1 << (INAT_FLAG_OFFS + 7))
3719 -/* Attribute making macros for attribute tables */
3720 -#define INAT_MAKE_PREFIX(pfx) (pfx << INAT_PFX_OFFS)
3721 -#define INAT_MAKE_ESCAPE(esc) (esc << INAT_ESC_OFFS)
3722 -#define INAT_MAKE_GROUP(grp) ((grp << INAT_GRP_OFFS) | INAT_MODRM)
3723 -#define INAT_MAKE_IMM(imm) (imm << INAT_IMM_OFFS)
3724 -
3725 -/* Attribute search APIs */
3726 -extern insn_attr_t inat_get_opcode_attribute(insn_byte_t opcode);
3727 -extern int inat_get_last_prefix_id(insn_byte_t last_pfx);
3728 -extern insn_attr_t inat_get_escape_attribute(insn_byte_t opcode,
3729 - int lpfx_id,
3730 - insn_attr_t esc_attr);
3731 -extern insn_attr_t inat_get_group_attribute(insn_byte_t modrm,
3732 - int lpfx_id,
3733 - insn_attr_t esc_attr);
3734 -extern insn_attr_t inat_get_avx_attribute(insn_byte_t opcode,
3735 - insn_byte_t vex_m,
3736 - insn_byte_t vex_pp);
3737 -
3738 -/* Attribute checking functions */
3739 -static inline int inat_is_legacy_prefix(insn_attr_t attr)
3740 -{
3741 - attr &= INAT_PFX_MASK;
3742 - return attr && attr <= INAT_LGCPFX_MAX;
3743 -}
3744 -
3745 -static inline int inat_is_address_size_prefix(insn_attr_t attr)
3746 -{
3747 - return (attr & INAT_PFX_MASK) == INAT_PFX_ADDRSZ;
3748 -}
3749 -
3750 -static inline int inat_is_operand_size_prefix(insn_attr_t attr)
3751 -{
3752 - return (attr & INAT_PFX_MASK) == INAT_PFX_OPNDSZ;
3753 -}
3754 -
3755 -static inline int inat_is_rex_prefix(insn_attr_t attr)
3756 -{
3757 - return (attr & INAT_PFX_MASK) == INAT_PFX_REX;
3758 -}
3759 -
3760 -static inline int inat_last_prefix_id(insn_attr_t attr)
3761 -{
3762 - if ((attr & INAT_PFX_MASK) > INAT_LSTPFX_MAX)
3763 - return 0;
3764 - else
3765 - return attr & INAT_PFX_MASK;
3766 -}
3767 -
3768 -static inline int inat_is_vex_prefix(insn_attr_t attr)
3769 -{
3770 - attr &= INAT_PFX_MASK;
3771 - return attr == INAT_PFX_VEX2 || attr == INAT_PFX_VEX3 ||
3772 - attr == INAT_PFX_EVEX;
3773 -}
3774 -
3775 -static inline int inat_is_evex_prefix(insn_attr_t attr)
3776 -{
3777 - return (attr & INAT_PFX_MASK) == INAT_PFX_EVEX;
3778 -}
3779 -
3780 -static inline int inat_is_vex3_prefix(insn_attr_t attr)
3781 -{
3782 - return (attr & INAT_PFX_MASK) == INAT_PFX_VEX3;
3783 -}
3784 -
3785 -static inline int inat_is_escape(insn_attr_t attr)
3786 -{
3787 - return attr & INAT_ESC_MASK;
3788 -}
3789 -
3790 -static inline int inat_escape_id(insn_attr_t attr)
3791 -{
3792 - return (attr & INAT_ESC_MASK) >> INAT_ESC_OFFS;
3793 -}
3794 -
3795 -static inline int inat_is_group(insn_attr_t attr)
3796 -{
3797 - return attr & INAT_GRP_MASK;
3798 -}
3799 -
3800 -static inline int inat_group_id(insn_attr_t attr)
3801 -{
3802 - return (attr & INAT_GRP_MASK) >> INAT_GRP_OFFS;
3803 -}
3804 -
3805 -static inline int inat_group_common_attribute(insn_attr_t attr)
3806 -{
3807 - return attr & ~INAT_GRP_MASK;
3808 -}
3809 -
3810 -static inline int inat_has_immediate(insn_attr_t attr)
3811 -{
3812 - return attr & INAT_IMM_MASK;
3813 -}
3814 -
3815 -static inline int inat_immediate_size(insn_attr_t attr)
3816 -{
3817 - return (attr & INAT_IMM_MASK) >> INAT_IMM_OFFS;
3818 -}
3819 -
3820 -static inline int inat_has_modrm(insn_attr_t attr)
3821 -{
3822 - return attr & INAT_MODRM;
3823 -}
3824 -
3825 -static inline int inat_is_force64(insn_attr_t attr)
3826 -{
3827 - return attr & INAT_FORCE64;
3828 -}
3829 -
3830 -static inline int inat_has_second_immediate(insn_attr_t attr)
3831 -{
3832 - return attr & INAT_SCNDIMM;
3833 -}
3834 -
3835 -static inline int inat_has_moffset(insn_attr_t attr)
3836 -{
3837 - return attr & INAT_MOFFSET;
3838 -}
3839 -
3840 -static inline int inat_has_variant(insn_attr_t attr)
3841 -{
3842 - return attr & INAT_VARIANT;
3843 -}
3844 -
3845 -static inline int inat_accept_vex(insn_attr_t attr)
3846 -{
3847 - return attr & INAT_VEXOK;
3848 -}
3849 -
3850 -static inline int inat_must_vex(insn_attr_t attr)
3851 -{
3852 - return attr & (INAT_VEXONLY | INAT_EVEXONLY);
3853 -}
3854 -
3855 -static inline int inat_must_evex(insn_attr_t attr)
3856 -{
3857 - return attr & INAT_EVEXONLY;
3858 -}
3859 -#endif
3860 diff --git a/tools/objtool/arch/x86/insn/inat_types.h b/tools/objtool/arch/x86/insn/inat_types.h
3861 deleted file mode 100644
3862 index cb3c20ce39cf..000000000000
3863 --- a/tools/objtool/arch/x86/insn/inat_types.h
3864 +++ /dev/null
3865 @@ -1,29 +0,0 @@
3866 -#ifndef _ASM_X86_INAT_TYPES_H
3867 -#define _ASM_X86_INAT_TYPES_H
3868 -/*
3869 - * x86 instruction attributes
3870 - *
3871 - * Written by Masami Hiramatsu <mhiramat@redhat.com>
3872 - *
3873 - * This program is free software; you can redistribute it and/or modify
3874 - * it under the terms of the GNU General Public License as published by
3875 - * the Free Software Foundation; either version 2 of the License, or
3876 - * (at your option) any later version.
3877 - *
3878 - * This program is distributed in the hope that it will be useful,
3879 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
3880 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3881 - * GNU General Public License for more details.
3882 - *
3883 - * You should have received a copy of the GNU General Public License
3884 - * along with this program; if not, write to the Free Software
3885 - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
3886 - *
3887 - */
3888 -
3889 -/* Instruction attributes */
3890 -typedef unsigned int insn_attr_t;
3891 -typedef unsigned char insn_byte_t;
3892 -typedef signed int insn_value_t;
3893 -
3894 -#endif
3895 diff --git a/tools/objtool/arch/x86/insn/insn.c b/tools/objtool/arch/x86/insn/insn.c
3896 deleted file mode 100644
3897 index ca983e2bea8b..000000000000
3898 --- a/tools/objtool/arch/x86/insn/insn.c
3899 +++ /dev/null
3900 @@ -1,606 +0,0 @@
3901 -/*
3902 - * x86 instruction analysis
3903 - *
3904 - * This program is free software; you can redistribute it and/or modify
3905 - * it under the terms of the GNU General Public License as published by
3906 - * the Free Software Foundation; either version 2 of the License, or
3907 - * (at your option) any later version.
3908 - *
3909 - * This program is distributed in the hope that it will be useful,
3910 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
3911 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3912 - * GNU General Public License for more details.
3913 - *
3914 - * You should have received a copy of the GNU General Public License
3915 - * along with this program; if not, write to the Free Software
3916 - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
3917 - *
3918 - * Copyright (C) IBM Corporation, 2002, 2004, 2009
3919 - */
3920 -
3921 -#ifdef __KERNEL__
3922 -#include <linux/string.h>
3923 -#else
3924 -#include <string.h>
3925 -#endif
3926 -#include "inat.h"
3927 -#include "insn.h"
3928 -
3929 -/* Verify next sizeof(t) bytes can be on the same instruction */
3930 -#define validate_next(t, insn, n) \
3931 - ((insn)->next_byte + sizeof(t) + n <= (insn)->end_kaddr)
3932 -
3933 -#define __get_next(t, insn) \
3934 - ({ t r = *(t*)insn->next_byte; insn->next_byte += sizeof(t); r; })
3935 -
3936 -#define __peek_nbyte_next(t, insn, n) \
3937 - ({ t r = *(t*)((insn)->next_byte + n); r; })
3938 -
3939 -#define get_next(t, insn) \
3940 - ({ if (unlikely(!validate_next(t, insn, 0))) goto err_out; __get_next(t, insn); })
3941 -
3942 -#define peek_nbyte_next(t, insn, n) \
3943 - ({ if (unlikely(!validate_next(t, insn, n))) goto err_out; __peek_nbyte_next(t, insn, n); })
3944 -
3945 -#define peek_next(t, insn) peek_nbyte_next(t, insn, 0)
3946 -
3947 -/**
3948 - * insn_init() - initialize struct insn
3949 - * @insn: &struct insn to be initialized
3950 - * @kaddr: address (in kernel memory) of instruction (or copy thereof)
3951 - * @x86_64: !0 for 64-bit kernel or 64-bit app
3952 - */
3953 -void insn_init(struct insn *insn, const void *kaddr, int buf_len, int x86_64)
3954 -{
3955 - /*
3956 - * Instructions longer than MAX_INSN_SIZE (15 bytes) are invalid
3957 - * even if the input buffer is long enough to hold them.
3958 - */
3959 - if (buf_len > MAX_INSN_SIZE)
3960 - buf_len = MAX_INSN_SIZE;
3961 -
3962 - memset(insn, 0, sizeof(*insn));
3963 - insn->kaddr = kaddr;
3964 - insn->end_kaddr = kaddr + buf_len;
3965 - insn->next_byte = kaddr;
3966 - insn->x86_64 = x86_64 ? 1 : 0;
3967 - insn->opnd_bytes = 4;
3968 - if (x86_64)
3969 - insn->addr_bytes = 8;
3970 - else
3971 - insn->addr_bytes = 4;
3972 -}
3973 -
3974 -/**
3975 - * insn_get_prefixes - scan x86 instruction prefix bytes
3976 - * @insn: &struct insn containing instruction
3977 - *
3978 - * Populates the @insn->prefixes bitmap, and updates @insn->next_byte
3979 - * to point to the (first) opcode. No effect if @insn->prefixes.got
3980 - * is already set.
3981 - */
3982 -void insn_get_prefixes(struct insn *insn)
3983 -{
3984 - struct insn_field *prefixes = &insn->prefixes;
3985 - insn_attr_t attr;
3986 - insn_byte_t b, lb;
3987 - int i, nb;
3988 -
3989 - if (prefixes->got)
3990 - return;
3991 -
3992 - nb = 0;
3993 - lb = 0;
3994 - b = peek_next(insn_byte_t, insn);
3995 - attr = inat_get_opcode_attribute(b);
3996 - while (inat_is_legacy_prefix(attr)) {
3997 - /* Skip if same prefix */
3998 - for (i = 0; i < nb; i++)
3999 - if (prefixes->bytes[i] == b)
4000 - goto found;
4001 - if (nb == 4)
4002 - /* Invalid instruction */
4003 - break;
4004 - prefixes->bytes[nb++] = b;
4005 - if (inat_is_address_size_prefix(attr)) {
4006 - /* address size switches 2/4 or 4/8 */
4007 - if (insn->x86_64)
4008 - insn->addr_bytes ^= 12;
4009 - else
4010 - insn->addr_bytes ^= 6;
4011 - } else if (inat_is_operand_size_prefix(attr)) {
4012 - /* oprand size switches 2/4 */
4013 - insn->opnd_bytes ^= 6;
4014 - }
4015 -found:
4016 - prefixes->nbytes++;
4017 - insn->next_byte++;
4018 - lb = b;
4019 - b = peek_next(insn_byte_t, insn);
4020 - attr = inat_get_opcode_attribute(b);
4021 - }
4022 - /* Set the last prefix */
4023 - if (lb && lb != insn->prefixes.bytes[3]) {
4024 - if (unlikely(insn->prefixes.bytes[3])) {
4025 - /* Swap the last prefix */
4026 - b = insn->prefixes.bytes[3];
4027 - for (i = 0; i < nb; i++)
4028 - if (prefixes->bytes[i] == lb)
4029 - prefixes->bytes[i] = b;
4030 - }
4031 - insn->prefixes.bytes[3] = lb;
4032 - }
4033 -
4034 - /* Decode REX prefix */
4035 - if (insn->x86_64) {
4036 - b = peek_next(insn_byte_t, insn);
4037 - attr = inat_get_opcode_attribute(b);
4038 - if (inat_is_rex_prefix(attr)) {
4039 - insn->rex_prefix.value = b;
4040 - insn->rex_prefix.nbytes = 1;
4041 - insn->next_byte++;
4042 - if (X86_REX_W(b))
4043 - /* REX.W overrides opnd_size */
4044 - insn->opnd_bytes = 8;
4045 - }
4046 - }
4047 - insn->rex_prefix.got = 1;
4048 -
4049 - /* Decode VEX prefix */
4050 - b = peek_next(insn_byte_t, insn);
4051 - attr = inat_get_opcode_attribute(b);
4052 - if (inat_is_vex_prefix(attr)) {
4053 - insn_byte_t b2 = peek_nbyte_next(insn_byte_t, insn, 1);
4054 - if (!insn->x86_64) {
4055 - /*
4056 - * In 32-bits mode, if the [7:6] bits (mod bits of
4057 - * ModRM) on the second byte are not 11b, it is
4058 - * LDS or LES or BOUND.
4059 - */
4060 - if (X86_MODRM_MOD(b2) != 3)
4061 - goto vex_end;
4062 - }
4063 - insn->vex_prefix.bytes[0] = b;
4064 - insn->vex_prefix.bytes[1] = b2;
4065 - if (inat_is_evex_prefix(attr)) {
4066 - b2 = peek_nbyte_next(insn_byte_t, insn, 2);
4067 - insn->vex_prefix.bytes[2] = b2;
4068 - b2 = peek_nbyte_next(insn_byte_t, insn, 3);
4069 - insn->vex_prefix.bytes[3] = b2;
4070 - insn->vex_prefix.nbytes = 4;
4071 - insn->next_byte += 4;
4072 - if (insn->x86_64 && X86_VEX_W(b2))
4073 - /* VEX.W overrides opnd_size */
4074 - insn->opnd_bytes = 8;
4075 - } else if (inat_is_vex3_prefix(attr)) {
4076 - b2 = peek_nbyte_next(insn_byte_t, insn, 2);
4077 - insn->vex_prefix.bytes[2] = b2;
4078 - insn->vex_prefix.nbytes = 3;
4079 - insn->next_byte += 3;
4080 - if (insn->x86_64 && X86_VEX_W(b2))
4081 - /* VEX.W overrides opnd_size */
4082 - insn->opnd_bytes = 8;
4083 - } else {
4084 - /*
4085 - * For VEX2, fake VEX3-like byte#2.
4086 - * Makes it easier to decode vex.W, vex.vvvv,
4087 - * vex.L and vex.pp. Masking with 0x7f sets vex.W == 0.
4088 - */
4089 - insn->vex_prefix.bytes[2] = b2 & 0x7f;
4090 - insn->vex_prefix.nbytes = 2;
4091 - insn->next_byte += 2;
4092 - }
4093 - }
4094 -vex_end:
4095 - insn->vex_prefix.got = 1;
4096 -
4097 - prefixes->got = 1;
4098 -
4099 -err_out:
4100 - return;
4101 -}
4102 -
4103 -/**
4104 - * insn_get_opcode - collect opcode(s)
4105 - * @insn: &struct insn containing instruction
4106 - *
4107 - * Populates @insn->opcode, updates @insn->next_byte to point past the
4108 - * opcode byte(s), and set @insn->attr (except for groups).
4109 - * If necessary, first collects any preceding (prefix) bytes.
4110 - * Sets @insn->opcode.value = opcode1. No effect if @insn->opcode.got
4111 - * is already 1.
4112 - */
4113 -void insn_get_opcode(struct insn *insn)
4114 -{
4115 - struct insn_field *opcode = &insn->opcode;
4116 - insn_byte_t op;
4117 - int pfx_id;
4118 - if (opcode->got)
4119 - return;
4120 - if (!insn->prefixes.got)
4121 - insn_get_prefixes(insn);
4122 -
4123 - /* Get first opcode */
4124 - op = get_next(insn_byte_t, insn);
4125 - opcode->bytes[0] = op;
4126 - opcode->nbytes = 1;
4127 -
4128 - /* Check if there is VEX prefix or not */
4129 - if (insn_is_avx(insn)) {
4130 - insn_byte_t m, p;
4131 - m = insn_vex_m_bits(insn);
4132 - p = insn_vex_p_bits(insn);
4133 - insn->attr = inat_get_avx_attribute(op, m, p);
4134 - if ((inat_must_evex(insn->attr) && !insn_is_evex(insn)) ||
4135 - (!inat_accept_vex(insn->attr) &&
4136 - !inat_is_group(insn->attr)))
4137 - insn->attr = 0; /* This instruction is bad */
4138 - goto end; /* VEX has only 1 byte for opcode */
4139 - }
4140 -
4141 - insn->attr = inat_get_opcode_attribute(op);
4142 - while (inat_is_escape(insn->attr)) {
4143 - /* Get escaped opcode */
4144 - op = get_next(insn_byte_t, insn);
4145 - opcode->bytes[opcode->nbytes++] = op;
4146 - pfx_id = insn_last_prefix_id(insn);
4147 - insn->attr = inat_get_escape_attribute(op, pfx_id, insn->attr);
4148 - }
4149 - if (inat_must_vex(insn->attr))
4150 - insn->attr = 0; /* This instruction is bad */
4151 -end:
4152 - opcode->got = 1;
4153 -
4154 -err_out:
4155 - return;
4156 -}
4157 -
4158 -/**
4159 - * insn_get_modrm - collect ModRM byte, if any
4160 - * @insn: &struct insn containing instruction
4161 - *
4162 - * Populates @insn->modrm and updates @insn->next_byte to point past the
4163 - * ModRM byte, if any. If necessary, first collects the preceding bytes
4164 - * (prefixes and opcode(s)). No effect if @insn->modrm.got is already 1.
4165 - */
4166 -void insn_get_modrm(struct insn *insn)
4167 -{
4168 - struct insn_field *modrm = &insn->modrm;
4169 - insn_byte_t pfx_id, mod;
4170 - if (modrm->got)
4171 - return;
4172 - if (!insn->opcode.got)
4173 - insn_get_opcode(insn);
4174 -
4175 - if (inat_has_modrm(insn->attr)) {
4176 - mod = get_next(insn_byte_t, insn);
4177 - modrm->value = mod;
4178 - modrm->nbytes = 1;
4179 - if (inat_is_group(insn->attr)) {
4180 - pfx_id = insn_last_prefix_id(insn);
4181 - insn->attr = inat_get_group_attribute(mod, pfx_id,
4182 - insn->attr);
4183 - if (insn_is_avx(insn) && !inat_accept_vex(insn->attr))
4184 - insn->attr = 0; /* This is bad */
4185 - }
4186 - }
4187 -
4188 - if (insn->x86_64 && inat_is_force64(insn->attr))
4189 - insn->opnd_bytes = 8;
4190 - modrm->got = 1;
4191 -
4192 -err_out:
4193 - return;
4194 -}
4195 -
4196 -
4197 -/**
4198 - * insn_rip_relative() - Does instruction use RIP-relative addressing mode?
4199 - * @insn: &struct insn containing instruction
4200 - *
4201 - * If necessary, first collects the instruction up to and including the
4202 - * ModRM byte. No effect if @insn->x86_64 is 0.
4203 - */
4204 -int insn_rip_relative(struct insn *insn)
4205 -{
4206 - struct insn_field *modrm = &insn->modrm;
4207 -
4208 - if (!insn->x86_64)
4209 - return 0;
4210 - if (!modrm->got)
4211 - insn_get_modrm(insn);
4212 - /*
4213 - * For rip-relative instructions, the mod field (top 2 bits)
4214 - * is zero and the r/m field (bottom 3 bits) is 0x5.
4215 - */
4216 - return (modrm->nbytes && (modrm->value & 0xc7) == 0x5);
4217 -}
4218 -
4219 -/**
4220 - * insn_get_sib() - Get the SIB byte of instruction
4221 - * @insn: &struct insn containing instruction
4222 - *
4223 - * If necessary, first collects the instruction up to and including the
4224 - * ModRM byte.
4225 - */
4226 -void insn_get_sib(struct insn *insn)
4227 -{
4228 - insn_byte_t modrm;
4229 -
4230 - if (insn->sib.got)
4231 - return;
4232 - if (!insn->modrm.got)
4233 - insn_get_modrm(insn);
4234 - if (insn->modrm.nbytes) {
4235 - modrm = (insn_byte_t)insn->modrm.value;
4236 - if (insn->addr_bytes != 2 &&
4237 - X86_MODRM_MOD(modrm) != 3 && X86_MODRM_RM(modrm) == 4) {
4238 - insn->sib.value = get_next(insn_byte_t, insn);
4239 - insn->sib.nbytes = 1;
4240 - }
4241 - }
4242 - insn->sib.got = 1;
4243 -
4244 -err_out:
4245 - return;
4246 -}
4247 -
4248 -
4249 -/**
4250 - * insn_get_displacement() - Get the displacement of instruction
4251 - * @insn: &struct insn containing instruction
4252 - *
4253 - * If necessary, first collects the instruction up to and including the
4254 - * SIB byte.
4255 - * Displacement value is sign-expanded.
4256 - */
4257 -void insn_get_displacement(struct insn *insn)
4258 -{
4259 - insn_byte_t mod, rm, base;
4260 -
4261 - if (insn->displacement.got)
4262 - return;
4263 - if (!insn->sib.got)
4264 - insn_get_sib(insn);
4265 - if (insn->modrm.nbytes) {
4266 - /*
4267 - * Interpreting the modrm byte:
4268 - * mod = 00 - no displacement fields (exceptions below)
4269 - * mod = 01 - 1-byte displacement field
4270 - * mod = 10 - displacement field is 4 bytes, or 2 bytes if
4271 - * address size = 2 (0x67 prefix in 32-bit mode)
4272 - * mod = 11 - no memory operand
4273 - *
4274 - * If address size = 2...
4275 - * mod = 00, r/m = 110 - displacement field is 2 bytes
4276 - *
4277 - * If address size != 2...
4278 - * mod != 11, r/m = 100 - SIB byte exists
4279 - * mod = 00, SIB base = 101 - displacement field is 4 bytes
4280 - * mod = 00, r/m = 101 - rip-relative addressing, displacement
4281 - * field is 4 bytes
4282 - */
4283 - mod = X86_MODRM_MOD(insn->modrm.value);
4284 - rm = X86_MODRM_RM(insn->modrm.value);
4285 - base = X86_SIB_BASE(insn->sib.value);
4286 - if (mod == 3)
4287 - goto out;
4288 - if (mod == 1) {
4289 - insn->displacement.value = get_next(signed char, insn);
4290 - insn->displacement.nbytes = 1;
4291 - } else if (insn->addr_bytes == 2) {
4292 - if ((mod == 0 && rm == 6) || mod == 2) {
4293 - insn->displacement.value =
4294 - get_next(short, insn);
4295 - insn->displacement.nbytes = 2;
4296 - }
4297 - } else {
4298 - if ((mod == 0 && rm == 5) || mod == 2 ||
4299 - (mod == 0 && base == 5)) {
4300 - insn->displacement.value = get_next(int, insn);
4301 - insn->displacement.nbytes = 4;
4302 - }
4303 - }
4304 - }
4305 -out:
4306 - insn->displacement.got = 1;
4307 -
4308 -err_out:
4309 - return;
4310 -}
4311 -
4312 -/* Decode moffset16/32/64. Return 0 if failed */
4313 -static int __get_moffset(struct insn *insn)
4314 -{
4315 - switch (insn->addr_bytes) {
4316 - case 2:
4317 - insn->moffset1.value = get_next(short, insn);
4318 - insn->moffset1.nbytes = 2;
4319 - break;
4320 - case 4:
4321 - insn->moffset1.value = get_next(int, insn);
4322 - insn->moffset1.nbytes = 4;
4323 - break;
4324 - case 8:
4325 - insn->moffset1.value = get_next(int, insn);
4326 - insn->moffset1.nbytes = 4;
4327 - insn->moffset2.value = get_next(int, insn);
4328 - insn->moffset2.nbytes = 4;
4329 - break;
4330 - default: /* opnd_bytes must be modified manually */
4331 - goto err_out;
4332 - }
4333 - insn->moffset1.got = insn->moffset2.got = 1;
4334 -
4335 - return 1;
4336 -
4337 -err_out:
4338 - return 0;
4339 -}
4340 -
4341 -/* Decode imm v32(Iz). Return 0 if failed */
4342 -static int __get_immv32(struct insn *insn)
4343 -{
4344 - switch (insn->opnd_bytes) {
4345 - case 2:
4346 - insn->immediate.value = get_next(short, insn);
4347 - insn->immediate.nbytes = 2;
4348 - break;
4349 - case 4:
4350 - case 8:
4351 - insn->immediate.value = get_next(int, insn);
4352 - insn->immediate.nbytes = 4;
4353 - break;
4354 - default: /* opnd_bytes must be modified manually */
4355 - goto err_out;
4356 - }
4357 -
4358 - return 1;
4359 -
4360 -err_out:
4361 - return 0;
4362 -}
4363 -
4364 -/* Decode imm v64(Iv/Ov), Return 0 if failed */
4365 -static int __get_immv(struct insn *insn)
4366 -{
4367 - switch (insn->opnd_bytes) {
4368 - case 2:
4369 - insn->immediate1.value = get_next(short, insn);
4370 - insn->immediate1.nbytes = 2;
4371 - break;
4372 - case 4:
4373 - insn->immediate1.value = get_next(int, insn);
4374 - insn->immediate1.nbytes = 4;
4375 - break;
4376 - case 8:
4377 - insn->immediate1.value = get_next(int, insn);
4378 - insn->immediate1.nbytes = 4;
4379 - insn->immediate2.value = get_next(int, insn);
4380 - insn->immediate2.nbytes = 4;
4381 - break;
4382 - default: /* opnd_bytes must be modified manually */
4383 - goto err_out;
4384 - }
4385 - insn->immediate1.got = insn->immediate2.got = 1;
4386 -
4387 - return 1;
4388 -err_out:
4389 - return 0;
4390 -}
4391 -
4392 -/* Decode ptr16:16/32(Ap) */
4393 -static int __get_immptr(struct insn *insn)
4394 -{
4395 - switch (insn->opnd_bytes) {
4396 - case 2:
4397 - insn->immediate1.value = get_next(short, insn);
4398 - insn->immediate1.nbytes = 2;
4399 - break;
4400 - case 4:
4401 - insn->immediate1.value = get_next(int, insn);
4402 - insn->immediate1.nbytes = 4;
4403 - break;
4404 - case 8:
4405 - /* ptr16:64 is not exist (no segment) */
4406 - return 0;
4407 - default: /* opnd_bytes must be modified manually */
4408 - goto err_out;
4409 - }
4410 - insn->immediate2.value = get_next(unsigned short, insn);
4411 - insn->immediate2.nbytes = 2;
4412 - insn->immediate1.got = insn->immediate2.got = 1;
4413 -
4414 - return 1;
4415 -err_out:
4416 - return 0;
4417 -}
4418 -
4419 -/**
4420 - * insn_get_immediate() - Get the immediates of instruction
4421 - * @insn: &struct insn containing instruction
4422 - *
4423 - * If necessary, first collects the instruction up to and including the
4424 - * displacement bytes.
4425 - * Basically, most of immediates are sign-expanded. Unsigned-value can be
4426 - * get by bit masking with ((1 << (nbytes * 8)) - 1)
4427 - */
4428 -void insn_get_immediate(struct insn *insn)
4429 -{
4430 - if (insn->immediate.got)
4431 - return;
4432 - if (!insn->displacement.got)
4433 - insn_get_displacement(insn);
4434 -
4435 - if (inat_has_moffset(insn->attr)) {
4436 - if (!__get_moffset(insn))
4437 - goto err_out;
4438 - goto done;
4439 - }
4440 -
4441 - if (!inat_has_immediate(insn->attr))
4442 - /* no immediates */
4443 - goto done;
4444 -
4445 - switch (inat_immediate_size(insn->attr)) {
4446 - case INAT_IMM_BYTE:
4447 - insn->immediate.value = get_next(signed char, insn);
4448 - insn->immediate.nbytes = 1;
4449 - break;
4450 - case INAT_IMM_WORD:
4451 - insn->immediate.value = get_next(short, insn);
4452 - insn->immediate.nbytes = 2;
4453 - break;
4454 - case INAT_IMM_DWORD:
4455 - insn->immediate.value = get_next(int, insn);
4456 - insn->immediate.nbytes = 4;
4457 - break;
4458 - case INAT_IMM_QWORD:
4459 - insn->immediate1.value = get_next(int, insn);
4460 - insn->immediate1.nbytes = 4;
4461 - insn->immediate2.value = get_next(int, insn);
4462 - insn->immediate2.nbytes = 4;
4463 - break;
4464 - case INAT_IMM_PTR:
4465 - if (!__get_immptr(insn))
4466 - goto err_out;
4467 - break;
4468 - case INAT_IMM_VWORD32:
4469 - if (!__get_immv32(insn))
4470 - goto err_out;
4471 - break;
4472 - case INAT_IMM_VWORD:
4473 - if (!__get_immv(insn))
4474 - goto err_out;
4475 - break;
4476 - default:
4477 - /* Here, insn must have an immediate, but failed */
4478 - goto err_out;
4479 - }
4480 - if (inat_has_second_immediate(insn->attr)) {
4481 - insn->immediate2.value = get_next(signed char, insn);
4482 - insn->immediate2.nbytes = 1;
4483 - }
4484 -done:
4485 - insn->immediate.got = 1;
4486 -
4487 -err_out:
4488 - return;
4489 -}
4490 -
4491 -/**
4492 - * insn_get_length() - Get the length of instruction
4493 - * @insn: &struct insn containing instruction
4494 - *
4495 - * If necessary, first collects the instruction up to and including the
4496 - * immediates bytes.
4497 - */
4498 -void insn_get_length(struct insn *insn)
4499 -{
4500 - if (insn->length)
4501 - return;
4502 - if (!insn->immediate.got)
4503 - insn_get_immediate(insn);
4504 - insn->length = (unsigned char)((unsigned long)insn->next_byte
4505 - - (unsigned long)insn->kaddr);
4506 -}
4507 diff --git a/tools/objtool/arch/x86/insn/insn.h b/tools/objtool/arch/x86/insn/insn.h
4508 deleted file mode 100644
4509 index e23578c7b1be..000000000000
4510 --- a/tools/objtool/arch/x86/insn/insn.h
4511 +++ /dev/null
4512 @@ -1,211 +0,0 @@
4513 -#ifndef _ASM_X86_INSN_H
4514 -#define _ASM_X86_INSN_H
4515 -/*
4516 - * x86 instruction analysis
4517 - *
4518 - * This program is free software; you can redistribute it and/or modify
4519 - * it under the terms of the GNU General Public License as published by
4520 - * the Free Software Foundation; either version 2 of the License, or
4521 - * (at your option) any later version.
4522 - *
4523 - * This program is distributed in the hope that it will be useful,
4524 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
4525 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4526 - * GNU General Public License for more details.
4527 - *
4528 - * You should have received a copy of the GNU General Public License
4529 - * along with this program; if not, write to the Free Software
4530 - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
4531 - *
4532 - * Copyright (C) IBM Corporation, 2009
4533 - */
4534 -
4535 -/* insn_attr_t is defined in inat.h */
4536 -#include "inat.h"
4537 -
4538 -struct insn_field {
4539 - union {
4540 - insn_value_t value;
4541 - insn_byte_t bytes[4];
4542 - };
4543 - /* !0 if we've run insn_get_xxx() for this field */
4544 - unsigned char got;
4545 - unsigned char nbytes;
4546 -};
4547 -
4548 -struct insn {
4549 - struct insn_field prefixes; /*
4550 - * Prefixes
4551 - * prefixes.bytes[3]: last prefix
4552 - */
4553 - struct insn_field rex_prefix; /* REX prefix */
4554 - struct insn_field vex_prefix; /* VEX prefix */
4555 - struct insn_field opcode; /*
4556 - * opcode.bytes[0]: opcode1
4557 - * opcode.bytes[1]: opcode2
4558 - * opcode.bytes[2]: opcode3
4559 - */
4560 - struct insn_field modrm;
4561 - struct insn_field sib;
4562 - struct insn_field displacement;
4563 - union {
4564 - struct insn_field immediate;
4565 - struct insn_field moffset1; /* for 64bit MOV */
4566 - struct insn_field immediate1; /* for 64bit imm or off16/32 */
4567 - };
4568 - union {
4569 - struct insn_field moffset2; /* for 64bit MOV */
4570 - struct insn_field immediate2; /* for 64bit imm or seg16 */
4571 - };
4572 -
4573 - insn_attr_t attr;
4574 - unsigned char opnd_bytes;
4575 - unsigned char addr_bytes;
4576 - unsigned char length;
4577 - unsigned char x86_64;
4578 -
4579 - const insn_byte_t *kaddr; /* kernel address of insn to analyze */
4580 - const insn_byte_t *end_kaddr; /* kernel address of last insn in buffer */
4581 - const insn_byte_t *next_byte;
4582 -};
4583 -
4584 -#define MAX_INSN_SIZE 15
4585 -
4586 -#define X86_MODRM_MOD(modrm) (((modrm) & 0xc0) >> 6)
4587 -#define X86_MODRM_REG(modrm) (((modrm) & 0x38) >> 3)
4588 -#define X86_MODRM_RM(modrm) ((modrm) & 0x07)
4589 -
4590 -#define X86_SIB_SCALE(sib) (((sib) & 0xc0) >> 6)
4591 -#define X86_SIB_INDEX(sib) (((sib) & 0x38) >> 3)
4592 -#define X86_SIB_BASE(sib) ((sib) & 0x07)
4593 -
4594 -#define X86_REX_W(rex) ((rex) & 8)
4595 -#define X86_REX_R(rex) ((rex) & 4)
4596 -#define X86_REX_X(rex) ((rex) & 2)
4597 -#define X86_REX_B(rex) ((rex) & 1)
4598 -
4599 -/* VEX bit flags */
4600 -#define X86_VEX_W(vex) ((vex) & 0x80) /* VEX3 Byte2 */
4601 -#define X86_VEX_R(vex) ((vex) & 0x80) /* VEX2/3 Byte1 */
4602 -#define X86_VEX_X(vex) ((vex) & 0x40) /* VEX3 Byte1 */
4603 -#define X86_VEX_B(vex) ((vex) & 0x20) /* VEX3 Byte1 */
4604 -#define X86_VEX_L(vex) ((vex) & 0x04) /* VEX3 Byte2, VEX2 Byte1 */
4605 -/* VEX bit fields */
4606 -#define X86_EVEX_M(vex) ((vex) & 0x03) /* EVEX Byte1 */
4607 -#define X86_VEX3_M(vex) ((vex) & 0x1f) /* VEX3 Byte1 */
4608 -#define X86_VEX2_M 1 /* VEX2.M always 1 */
4609 -#define X86_VEX_V(vex) (((vex) & 0x78) >> 3) /* VEX3 Byte2, VEX2 Byte1 */
4610 -#define X86_VEX_P(vex) ((vex) & 0x03) /* VEX3 Byte2, VEX2 Byte1 */
4611 -#define X86_VEX_M_MAX 0x1f /* VEX3.M Maximum value */
4612 -
4613 -extern void insn_init(struct insn *insn, const void *kaddr, int buf_len, int x86_64);
4614 -extern void insn_get_prefixes(struct insn *insn);
4615 -extern void insn_get_opcode(struct insn *insn);
4616 -extern void insn_get_modrm(struct insn *insn);
4617 -extern void insn_get_sib(struct insn *insn);
4618 -extern void insn_get_displacement(struct insn *insn);
4619 -extern void insn_get_immediate(struct insn *insn);
4620 -extern void insn_get_length(struct insn *insn);
4621 -
4622 -/* Attribute will be determined after getting ModRM (for opcode groups) */
4623 -static inline void insn_get_attribute(struct insn *insn)
4624 -{
4625 - insn_get_modrm(insn);
4626 -}
4627 -
4628 -/* Instruction uses RIP-relative addressing */
4629 -extern int insn_rip_relative(struct insn *insn);
4630 -
4631 -/* Init insn for kernel text */
4632 -static inline void kernel_insn_init(struct insn *insn,
4633 - const void *kaddr, int buf_len)
4634 -{
4635 -#ifdef CONFIG_X86_64
4636 - insn_init(insn, kaddr, buf_len, 1);
4637 -#else /* CONFIG_X86_32 */
4638 - insn_init(insn, kaddr, buf_len, 0);
4639 -#endif
4640 -}
4641 -
4642 -static inline int insn_is_avx(struct insn *insn)
4643 -{
4644 - if (!insn->prefixes.got)
4645 - insn_get_prefixes(insn);
4646 - return (insn->vex_prefix.value != 0);
4647 -}
4648 -
4649 -static inline int insn_is_evex(struct insn *insn)
4650 -{
4651 - if (!insn->prefixes.got)
4652 - insn_get_prefixes(insn);
4653 - return (insn->vex_prefix.nbytes == 4);
4654 -}
4655 -
4656 -/* Ensure this instruction is decoded completely */
4657 -static inline int insn_complete(struct insn *insn)
4658 -{
4659 - return insn->opcode.got && insn->modrm.got && insn->sib.got &&
4660 - insn->displacement.got && insn->immediate.got;
4661 -}
4662 -
4663 -static inline insn_byte_t insn_vex_m_bits(struct insn *insn)
4664 -{
4665 - if (insn->vex_prefix.nbytes == 2) /* 2 bytes VEX */
4666 - return X86_VEX2_M;
4667 - else if (insn->vex_prefix.nbytes == 3) /* 3 bytes VEX */
4668 - return X86_VEX3_M(insn->vex_prefix.bytes[1]);
4669 - else /* EVEX */
4670 - return X86_EVEX_M(insn->vex_prefix.bytes[1]);
4671 -}
4672 -
4673 -static inline insn_byte_t insn_vex_p_bits(struct insn *insn)
4674 -{
4675 - if (insn->vex_prefix.nbytes == 2) /* 2 bytes VEX */
4676 - return X86_VEX_P(insn->vex_prefix.bytes[1]);
4677 - else
4678 - return X86_VEX_P(insn->vex_prefix.bytes[2]);
4679 -}
4680 -
4681 -/* Get the last prefix id from last prefix or VEX prefix */
4682 -static inline int insn_last_prefix_id(struct insn *insn)
4683 -{
4684 - if (insn_is_avx(insn))
4685 - return insn_vex_p_bits(insn); /* VEX_p is a SIMD prefix id */
4686 -
4687 - if (insn->prefixes.bytes[3])
4688 - return inat_get_last_prefix_id(insn->prefixes.bytes[3]);
4689 -
4690 - return 0;
4691 -}
4692 -
4693 -/* Offset of each field from kaddr */
4694 -static inline int insn_offset_rex_prefix(struct insn *insn)
4695 -{
4696 - return insn->prefixes.nbytes;
4697 -}
4698 -static inline int insn_offset_vex_prefix(struct insn *insn)
4699 -{
4700 - return insn_offset_rex_prefix(insn) + insn->rex_prefix.nbytes;
4701 -}
4702 -static inline int insn_offset_opcode(struct insn *insn)
4703 -{
4704 - return insn_offset_vex_prefix(insn) + insn->vex_prefix.nbytes;
4705 -}
4706 -static inline int insn_offset_modrm(struct insn *insn)
4707 -{
4708 - return insn_offset_opcode(insn) + insn->opcode.nbytes;
4709 -}
4710 -static inline int insn_offset_sib(struct insn *insn)
4711 -{
4712 - return insn_offset_modrm(insn) + insn->modrm.nbytes;
4713 -}
4714 -static inline int insn_offset_displacement(struct insn *insn)
4715 -{
4716 - return insn_offset_sib(insn) + insn->sib.nbytes;
4717 -}
4718 -static inline int insn_offset_immediate(struct insn *insn)
4719 -{
4720 - return insn_offset_displacement(insn) + insn->displacement.nbytes;
4721 -}
4722 -
4723 -#endif /* _ASM_X86_INSN_H */
4724 diff --git a/tools/objtool/arch/x86/insn/x86-opcode-map.txt b/tools/objtool/arch/x86/insn/x86-opcode-map.txt
4725 deleted file mode 100644
4726 index 1754e094bc28..000000000000
4727 --- a/tools/objtool/arch/x86/insn/x86-opcode-map.txt
4728 +++ /dev/null
4729 @@ -1,1063 +0,0 @@
4730 -# x86 Opcode Maps
4731 -#
4732 -# This is (mostly) based on following documentations.
4733 -# - Intel(R) 64 and IA-32 Architectures Software Developer's Manual Vol.2C
4734 -# (#326018-047US, June 2013)
4735 -#
4736 -#<Opcode maps>
4737 -# Table: table-name
4738 -# Referrer: escaped-name
4739 -# AVXcode: avx-code
4740 -# opcode: mnemonic|GrpXXX [operand1[,operand2...]] [(extra1)[,(extra2)...] [| 2nd-mnemonic ...]
4741 -# (or)
4742 -# opcode: escape # escaped-name
4743 -# EndTable
4744 -#
4745 -# mnemonics that begin with lowercase 'v' accept a VEX or EVEX prefix
4746 -# mnemonics that begin with lowercase 'k' accept a VEX prefix
4747 -#
4748 -#<group maps>
4749 -# GrpTable: GrpXXX
4750 -# reg: mnemonic [operand1[,operand2...]] [(extra1)[,(extra2)...] [| 2nd-mnemonic ...]
4751 -# EndTable
4752 -#
4753 -# AVX Superscripts
4754 -# (ev): this opcode requires EVEX prefix.
4755 -# (evo): this opcode is changed by EVEX prefix (EVEX opcode)
4756 -# (v): this opcode requires VEX prefix.
4757 -# (v1): this opcode only supports 128bit VEX.
4758 -#
4759 -# Last Prefix Superscripts
4760 -# - (66): the last prefix is 0x66
4761 -# - (F3): the last prefix is 0xF3
4762 -# - (F2): the last prefix is 0xF2
4763 -# - (!F3) : the last prefix is not 0xF3 (including non-last prefix case)
4764 -# - (66&F2): Both 0x66 and 0xF2 prefixes are specified.
4765 -
4766 -Table: one byte opcode
4767 -Referrer:
4768 -AVXcode:
4769 -# 0x00 - 0x0f
4770 -00: ADD Eb,Gb
4771 -01: ADD Ev,Gv
4772 -02: ADD Gb,Eb
4773 -03: ADD Gv,Ev
4774 -04: ADD AL,Ib
4775 -05: ADD rAX,Iz
4776 -06: PUSH ES (i64)
4777 -07: POP ES (i64)
4778 -08: OR Eb,Gb
4779 -09: OR Ev,Gv
4780 -0a: OR Gb,Eb
4781 -0b: OR Gv,Ev
4782 -0c: OR AL,Ib
4783 -0d: OR rAX,Iz
4784 -0e: PUSH CS (i64)
4785 -0f: escape # 2-byte escape
4786 -# 0x10 - 0x1f
4787 -10: ADC Eb,Gb
4788 -11: ADC Ev,Gv
4789 -12: ADC Gb,Eb
4790 -13: ADC Gv,Ev
4791 -14: ADC AL,Ib
4792 -15: ADC rAX,Iz
4793 -16: PUSH SS (i64)
4794 -17: POP SS (i64)
4795 -18: SBB Eb,Gb
4796 -19: SBB Ev,Gv
4797 -1a: SBB Gb,Eb
4798 -1b: SBB Gv,Ev
4799 -1c: SBB AL,Ib
4800 -1d: SBB rAX,Iz
4801 -1e: PUSH DS (i64)
4802 -1f: POP DS (i64)
4803 -# 0x20 - 0x2f
4804 -20: AND Eb,Gb
4805 -21: AND Ev,Gv
4806 -22: AND Gb,Eb
4807 -23: AND Gv,Ev
4808 -24: AND AL,Ib
4809 -25: AND rAx,Iz
4810 -26: SEG=ES (Prefix)
4811 -27: DAA (i64)
4812 -28: SUB Eb,Gb
4813 -29: SUB Ev,Gv
4814 -2a: SUB Gb,Eb
4815 -2b: SUB Gv,Ev
4816 -2c: SUB AL,Ib
4817 -2d: SUB rAX,Iz
4818 -2e: SEG=CS (Prefix)
4819 -2f: DAS (i64)
4820 -# 0x30 - 0x3f
4821 -30: XOR Eb,Gb
4822 -31: XOR Ev,Gv
4823 -32: XOR Gb,Eb
4824 -33: XOR Gv,Ev
4825 -34: XOR AL,Ib
4826 -35: XOR rAX,Iz
4827 -36: SEG=SS (Prefix)
4828 -37: AAA (i64)
4829 -38: CMP Eb,Gb
4830 -39: CMP Ev,Gv
4831 -3a: CMP Gb,Eb
4832 -3b: CMP Gv,Ev
4833 -3c: CMP AL,Ib
4834 -3d: CMP rAX,Iz
4835 -3e: SEG=DS (Prefix)
4836 -3f: AAS (i64)
4837 -# 0x40 - 0x4f
4838 -40: INC eAX (i64) | REX (o64)
4839 -41: INC eCX (i64) | REX.B (o64)
4840 -42: INC eDX (i64) | REX.X (o64)
4841 -43: INC eBX (i64) | REX.XB (o64)
4842 -44: INC eSP (i64) | REX.R (o64)
4843 -45: INC eBP (i64) | REX.RB (o64)
4844 -46: INC eSI (i64) | REX.RX (o64)
4845 -47: INC eDI (i64) | REX.RXB (o64)
4846 -48: DEC eAX (i64) | REX.W (o64)
4847 -49: DEC eCX (i64) | REX.WB (o64)
4848 -4a: DEC eDX (i64) | REX.WX (o64)
4849 -4b: DEC eBX (i64) | REX.WXB (o64)
4850 -4c: DEC eSP (i64) | REX.WR (o64)
4851 -4d: DEC eBP (i64) | REX.WRB (o64)
4852 -4e: DEC eSI (i64) | REX.WRX (o64)
4853 -4f: DEC eDI (i64) | REX.WRXB (o64)
4854 -# 0x50 - 0x5f
4855 -50: PUSH rAX/r8 (d64)
4856 -51: PUSH rCX/r9 (d64)
4857 -52: PUSH rDX/r10 (d64)
4858 -53: PUSH rBX/r11 (d64)
4859 -54: PUSH rSP/r12 (d64)
4860 -55: PUSH rBP/r13 (d64)
4861 -56: PUSH rSI/r14 (d64)
4862 -57: PUSH rDI/r15 (d64)
4863 -58: POP rAX/r8 (d64)
4864 -59: POP rCX/r9 (d64)
4865 -5a: POP rDX/r10 (d64)
4866 -5b: POP rBX/r11 (d64)
4867 -5c: POP rSP/r12 (d64)
4868 -5d: POP rBP/r13 (d64)
4869 -5e: POP rSI/r14 (d64)
4870 -5f: POP rDI/r15 (d64)
4871 -# 0x60 - 0x6f
4872 -60: PUSHA/PUSHAD (i64)
4873 -61: POPA/POPAD (i64)
4874 -62: BOUND Gv,Ma (i64) | EVEX (Prefix)
4875 -63: ARPL Ew,Gw (i64) | MOVSXD Gv,Ev (o64)
4876 -64: SEG=FS (Prefix)
4877 -65: SEG=GS (Prefix)
4878 -66: Operand-Size (Prefix)
4879 -67: Address-Size (Prefix)
4880 -68: PUSH Iz (d64)
4881 -69: IMUL Gv,Ev,Iz
4882 -6a: PUSH Ib (d64)
4883 -6b: IMUL Gv,Ev,Ib
4884 -6c: INS/INSB Yb,DX
4885 -6d: INS/INSW/INSD Yz,DX
4886 -6e: OUTS/OUTSB DX,Xb
4887 -6f: OUTS/OUTSW/OUTSD DX,Xz
4888 -# 0x70 - 0x7f
4889 -70: JO Jb
4890 -71: JNO Jb
4891 -72: JB/JNAE/JC Jb
4892 -73: JNB/JAE/JNC Jb
4893 -74: JZ/JE Jb
4894 -75: JNZ/JNE Jb
4895 -76: JBE/JNA Jb
4896 -77: JNBE/JA Jb
4897 -78: JS Jb
4898 -79: JNS Jb
4899 -7a: JP/JPE Jb
4900 -7b: JNP/JPO Jb
4901 -7c: JL/JNGE Jb
4902 -7d: JNL/JGE Jb
4903 -7e: JLE/JNG Jb
4904 -7f: JNLE/JG Jb
4905 -# 0x80 - 0x8f
4906 -80: Grp1 Eb,Ib (1A)
4907 -81: Grp1 Ev,Iz (1A)
4908 -82: Grp1 Eb,Ib (1A),(i64)
4909 -83: Grp1 Ev,Ib (1A)
4910 -84: TEST Eb,Gb
4911 -85: TEST Ev,Gv
4912 -86: XCHG Eb,Gb
4913 -87: XCHG Ev,Gv
4914 -88: MOV Eb,Gb
4915 -89: MOV Ev,Gv
4916 -8a: MOV Gb,Eb
4917 -8b: MOV Gv,Ev
4918 -8c: MOV Ev,Sw
4919 -8d: LEA Gv,M
4920 -8e: MOV Sw,Ew
4921 -8f: Grp1A (1A) | POP Ev (d64)
4922 -# 0x90 - 0x9f
4923 -90: NOP | PAUSE (F3) | XCHG r8,rAX
4924 -91: XCHG rCX/r9,rAX
4925 -92: XCHG rDX/r10,rAX
4926 -93: XCHG rBX/r11,rAX
4927 -94: XCHG rSP/r12,rAX
4928 -95: XCHG rBP/r13,rAX
4929 -96: XCHG rSI/r14,rAX
4930 -97: XCHG rDI/r15,rAX
4931 -98: CBW/CWDE/CDQE
4932 -99: CWD/CDQ/CQO
4933 -9a: CALLF Ap (i64)
4934 -9b: FWAIT/WAIT
4935 -9c: PUSHF/D/Q Fv (d64)
4936 -9d: POPF/D/Q Fv (d64)
4937 -9e: SAHF
4938 -9f: LAHF
4939 -# 0xa0 - 0xaf
4940 -a0: MOV AL,Ob
4941 -a1: MOV rAX,Ov
4942 -a2: MOV Ob,AL
4943 -a3: MOV Ov,rAX
4944 -a4: MOVS/B Yb,Xb
4945 -a5: MOVS/W/D/Q Yv,Xv
4946 -a6: CMPS/B Xb,Yb
4947 -a7: CMPS/W/D Xv,Yv
4948 -a8: TEST AL,Ib
4949 -a9: TEST rAX,Iz
4950 -aa: STOS/B Yb,AL
4951 -ab: STOS/W/D/Q Yv,rAX
4952 -ac: LODS/B AL,Xb
4953 -ad: LODS/W/D/Q rAX,Xv
4954 -ae: SCAS/B AL,Yb
4955 -# Note: The May 2011 Intel manual shows Xv for the second parameter of the
4956 -# next instruction but Yv is correct
4957 -af: SCAS/W/D/Q rAX,Yv
4958 -# 0xb0 - 0xbf
4959 -b0: MOV AL/R8L,Ib
4960 -b1: MOV CL/R9L,Ib
4961 -b2: MOV DL/R10L,Ib
4962 -b3: MOV BL/R11L,Ib
4963 -b4: MOV AH/R12L,Ib
4964 -b5: MOV CH/R13L,Ib
4965 -b6: MOV DH/R14L,Ib
4966 -b7: MOV BH/R15L,Ib
4967 -b8: MOV rAX/r8,Iv
4968 -b9: MOV rCX/r9,Iv
4969 -ba: MOV rDX/r10,Iv
4970 -bb: MOV rBX/r11,Iv
4971 -bc: MOV rSP/r12,Iv
4972 -bd: MOV rBP/r13,Iv
4973 -be: MOV rSI/r14,Iv
4974 -bf: MOV rDI/r15,Iv
4975 -# 0xc0 - 0xcf
4976 -c0: Grp2 Eb,Ib (1A)
4977 -c1: Grp2 Ev,Ib (1A)
4978 -c2: RETN Iw (f64)
4979 -c3: RETN
4980 -c4: LES Gz,Mp (i64) | VEX+2byte (Prefix)
4981 -c5: LDS Gz,Mp (i64) | VEX+1byte (Prefix)
4982 -c6: Grp11A Eb,Ib (1A)
4983 -c7: Grp11B Ev,Iz (1A)
4984 -c8: ENTER Iw,Ib
4985 -c9: LEAVE (d64)
4986 -ca: RETF Iw
4987 -cb: RETF
4988 -cc: INT3
4989 -cd: INT Ib
4990 -ce: INTO (i64)
4991 -cf: IRET/D/Q
4992 -# 0xd0 - 0xdf
4993 -d0: Grp2 Eb,1 (1A)
4994 -d1: Grp2 Ev,1 (1A)
4995 -d2: Grp2 Eb,CL (1A)
4996 -d3: Grp2 Ev,CL (1A)
4997 -d4: AAM Ib (i64)
4998 -d5: AAD Ib (i64)
4999 -d6:
5000 -d7: XLAT/XLATB
5001 -d8: ESC
5002 -d9: ESC
5003 -da: ESC
5004 -db: ESC
5005 -dc: ESC
5006 -dd: ESC
5007 -de: ESC
5008 -df: ESC
5009 -# 0xe0 - 0xef
5010 -# Note: "forced64" is Intel CPU behavior: they ignore 0x66 prefix
5011 -# in 64-bit mode. AMD CPUs accept 0x66 prefix, it causes RIP truncation
5012 -# to 16 bits. In 32-bit mode, 0x66 is accepted by both Intel and AMD.
5013 -e0: LOOPNE/LOOPNZ Jb (f64)
5014 -e1: LOOPE/LOOPZ Jb (f64)
5015 -e2: LOOP Jb (f64)
5016 -e3: JrCXZ Jb (f64)
5017 -e4: IN AL,Ib
5018 -e5: IN eAX,Ib
5019 -e6: OUT Ib,AL
5020 -e7: OUT Ib,eAX
5021 -# With 0x66 prefix in 64-bit mode, for AMD CPUs immediate offset
5022 -# in "near" jumps and calls is 16-bit. For CALL,
5023 -# push of return address is 16-bit wide, RSP is decremented by 2
5024 -# but is not truncated to 16 bits, unlike RIP.
5025 -e8: CALL Jz (f64)
5026 -e9: JMP-near Jz (f64)
5027 -ea: JMP-far Ap (i64)
5028 -eb: JMP-short Jb (f64)
5029 -ec: IN AL,DX
5030 -ed: IN eAX,DX
5031 -ee: OUT DX,AL
5032 -ef: OUT DX,eAX
5033 -# 0xf0 - 0xff
5034 -f0: LOCK (Prefix)
5035 -f1:
5036 -f2: REPNE (Prefix) | XACQUIRE (Prefix)
5037 -f3: REP/REPE (Prefix) | XRELEASE (Prefix)
5038 -f4: HLT
5039 -f5: CMC
5040 -f6: Grp3_1 Eb (1A)
5041 -f7: Grp3_2 Ev (1A)
5042 -f8: CLC
5043 -f9: STC
5044 -fa: CLI
5045 -fb: STI
5046 -fc: CLD
5047 -fd: STD
5048 -fe: Grp4 (1A)
5049 -ff: Grp5 (1A)
5050 -EndTable
5051 -
5052 -Table: 2-byte opcode (0x0f)
5053 -Referrer: 2-byte escape
5054 -AVXcode: 1
5055 -# 0x0f 0x00-0x0f
5056 -00: Grp6 (1A)
5057 -01: Grp7 (1A)
5058 -02: LAR Gv,Ew
5059 -03: LSL Gv,Ew
5060 -04:
5061 -05: SYSCALL (o64)
5062 -06: CLTS
5063 -07: SYSRET (o64)
5064 -08: INVD
5065 -09: WBINVD
5066 -0a:
5067 -0b: UD2 (1B)
5068 -0c:
5069 -# AMD's prefetch group. Intel supports prefetchw(/1) only.
5070 -0d: GrpP
5071 -0e: FEMMS
5072 -# 3DNow! uses the last imm byte as opcode extension.
5073 -0f: 3DNow! Pq,Qq,Ib
5074 -# 0x0f 0x10-0x1f
5075 -# NOTE: According to Intel SDM opcode map, vmovups and vmovupd has no operands
5076 -# but it actually has operands. And also, vmovss and vmovsd only accept 128bit.
5077 -# MOVSS/MOVSD has too many forms(3) on SDM. This map just shows a typical form.
5078 -# Many AVX instructions lack v1 superscript, according to Intel AVX-Prgramming
5079 -# Reference A.1
5080 -10: vmovups Vps,Wps | vmovupd Vpd,Wpd (66) | vmovss Vx,Hx,Wss (F3),(v1) | vmovsd Vx,Hx,Wsd (F2),(v1)
5081 -11: vmovups Wps,Vps | vmovupd Wpd,Vpd (66) | vmovss Wss,Hx,Vss (F3),(v1) | vmovsd Wsd,Hx,Vsd (F2),(v1)
5082 -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)
5083 -13: vmovlps Mq,Vq (v1) | vmovlpd Mq,Vq (66),(v1)
5084 -14: vunpcklps Vx,Hx,Wx | vunpcklpd Vx,Hx,Wx (66)
5085 -15: vunpckhps Vx,Hx,Wx | vunpckhpd Vx,Hx,Wx (66)
5086 -16: vmovhps Vdq,Hq,Mq (v1) | vmovlhps Vdq,Hq,Uq (v1) | vmovhpd Vdq,Hq,Mq (66),(v1) | vmovshdup Vx,Wx (F3)
5087 -17: vmovhps Mq,Vq (v1) | vmovhpd Mq,Vq (66),(v1)
5088 -18: Grp16 (1A)
5089 -19:
5090 -# Intel SDM opcode map does not list MPX instructions. For now using Gv for
5091 -# bnd registers and Ev for everything else is OK because the instruction
5092 -# decoder does not use the information except as an indication that there is
5093 -# a ModR/M byte.
5094 -1a: BNDCL Gv,Ev (F3) | BNDCU Gv,Ev (F2) | BNDMOV Gv,Ev (66) | BNDLDX Gv,Ev
5095 -1b: BNDCN Gv,Ev (F2) | BNDMOV Ev,Gv (66) | BNDMK Gv,Ev (F3) | BNDSTX Ev,Gv
5096 -1c:
5097 -1d:
5098 -1e:
5099 -1f: NOP Ev
5100 -# 0x0f 0x20-0x2f
5101 -20: MOV Rd,Cd
5102 -21: MOV Rd,Dd
5103 -22: MOV Cd,Rd
5104 -23: MOV Dd,Rd
5105 -24:
5106 -25:
5107 -26:
5108 -27:
5109 -28: vmovaps Vps,Wps | vmovapd Vpd,Wpd (66)
5110 -29: vmovaps Wps,Vps | vmovapd Wpd,Vpd (66)
5111 -2a: cvtpi2ps Vps,Qpi | cvtpi2pd Vpd,Qpi (66) | vcvtsi2ss Vss,Hss,Ey (F3),(v1) | vcvtsi2sd Vsd,Hsd,Ey (F2),(v1)
5112 -2b: vmovntps Mps,Vps | vmovntpd Mpd,Vpd (66)
5113 -2c: cvttps2pi Ppi,Wps | cvttpd2pi Ppi,Wpd (66) | vcvttss2si Gy,Wss (F3),(v1) | vcvttsd2si Gy,Wsd (F2),(v1)
5114 -2d: cvtps2pi Ppi,Wps | cvtpd2pi Qpi,Wpd (66) | vcvtss2si Gy,Wss (F3),(v1) | vcvtsd2si Gy,Wsd (F2),(v1)
5115 -2e: vucomiss Vss,Wss (v1) | vucomisd Vsd,Wsd (66),(v1)
5116 -2f: vcomiss Vss,Wss (v1) | vcomisd Vsd,Wsd (66),(v1)
5117 -# 0x0f 0x30-0x3f
5118 -30: WRMSR
5119 -31: RDTSC
5120 -32: RDMSR
5121 -33: RDPMC
5122 -34: SYSENTER
5123 -35: SYSEXIT
5124 -36:
5125 -37: GETSEC
5126 -38: escape # 3-byte escape 1
5127 -39:
5128 -3a: escape # 3-byte escape 2
5129 -3b:
5130 -3c:
5131 -3d:
5132 -3e:
5133 -3f:
5134 -# 0x0f 0x40-0x4f
5135 -40: CMOVO Gv,Ev
5136 -41: CMOVNO Gv,Ev | kandw/q Vk,Hk,Uk | kandb/d Vk,Hk,Uk (66)
5137 -42: CMOVB/C/NAE Gv,Ev | kandnw/q Vk,Hk,Uk | kandnb/d Vk,Hk,Uk (66)
5138 -43: CMOVAE/NB/NC Gv,Ev
5139 -44: CMOVE/Z Gv,Ev | knotw/q Vk,Uk | knotb/d Vk,Uk (66)
5140 -45: CMOVNE/NZ Gv,Ev | korw/q Vk,Hk,Uk | korb/d Vk,Hk,Uk (66)
5141 -46: CMOVBE/NA Gv,Ev | kxnorw/q Vk,Hk,Uk | kxnorb/d Vk,Hk,Uk (66)
5142 -47: CMOVA/NBE Gv,Ev | kxorw/q Vk,Hk,Uk | kxorb/d Vk,Hk,Uk (66)
5143 -48: CMOVS Gv,Ev
5144 -49: CMOVNS Gv,Ev
5145 -4a: CMOVP/PE Gv,Ev | kaddw/q Vk,Hk,Uk | kaddb/d Vk,Hk,Uk (66)
5146 -4b: CMOVNP/PO Gv,Ev | kunpckbw Vk,Hk,Uk (66) | kunpckwd/dq Vk,Hk,Uk
5147 -4c: CMOVL/NGE Gv,Ev
5148 -4d: CMOVNL/GE Gv,Ev
5149 -4e: CMOVLE/NG Gv,Ev
5150 -4f: CMOVNLE/G Gv,Ev
5151 -# 0x0f 0x50-0x5f
5152 -50: vmovmskps Gy,Ups | vmovmskpd Gy,Upd (66)
5153 -51: vsqrtps Vps,Wps | vsqrtpd Vpd,Wpd (66) | vsqrtss Vss,Hss,Wss (F3),(v1) | vsqrtsd Vsd,Hsd,Wsd (F2),(v1)
5154 -52: vrsqrtps Vps,Wps | vrsqrtss Vss,Hss,Wss (F3),(v1)
5155 -53: vrcpps Vps,Wps | vrcpss Vss,Hss,Wss (F3),(v1)
5156 -54: vandps Vps,Hps,Wps | vandpd Vpd,Hpd,Wpd (66)
5157 -55: vandnps Vps,Hps,Wps | vandnpd Vpd,Hpd,Wpd (66)
5158 -56: vorps Vps,Hps,Wps | vorpd Vpd,Hpd,Wpd (66)
5159 -57: vxorps Vps,Hps,Wps | vxorpd Vpd,Hpd,Wpd (66)
5160 -58: vaddps Vps,Hps,Wps | vaddpd Vpd,Hpd,Wpd (66) | vaddss Vss,Hss,Wss (F3),(v1) | vaddsd Vsd,Hsd,Wsd (F2),(v1)
5161 -59: vmulps Vps,Hps,Wps | vmulpd Vpd,Hpd,Wpd (66) | vmulss Vss,Hss,Wss (F3),(v1) | vmulsd Vsd,Hsd,Wsd (F2),(v1)
5162 -5a: vcvtps2pd Vpd,Wps | vcvtpd2ps Vps,Wpd (66) | vcvtss2sd Vsd,Hx,Wss (F3),(v1) | vcvtsd2ss Vss,Hx,Wsd (F2),(v1)
5163 -5b: vcvtdq2ps Vps,Wdq | vcvtqq2ps Vps,Wqq (evo) | vcvtps2dq Vdq,Wps (66) | vcvttps2dq Vdq,Wps (F3)
5164 -5c: vsubps Vps,Hps,Wps | vsubpd Vpd,Hpd,Wpd (66) | vsubss Vss,Hss,Wss (F3),(v1) | vsubsd Vsd,Hsd,Wsd (F2),(v1)
5165 -5d: vminps Vps,Hps,Wps | vminpd Vpd,Hpd,Wpd (66) | vminss Vss,Hss,Wss (F3),(v1) | vminsd Vsd,Hsd,Wsd (F2),(v1)
5166 -5e: vdivps Vps,Hps,Wps | vdivpd Vpd,Hpd,Wpd (66) | vdivss Vss,Hss,Wss (F3),(v1) | vdivsd Vsd,Hsd,Wsd (F2),(v1)
5167 -5f: vmaxps Vps,Hps,Wps | vmaxpd Vpd,Hpd,Wpd (66) | vmaxss Vss,Hss,Wss (F3),(v1) | vmaxsd Vsd,Hsd,Wsd (F2),(v1)
5168 -# 0x0f 0x60-0x6f
5169 -60: punpcklbw Pq,Qd | vpunpcklbw Vx,Hx,Wx (66),(v1)
5170 -61: punpcklwd Pq,Qd | vpunpcklwd Vx,Hx,Wx (66),(v1)
5171 -62: punpckldq Pq,Qd | vpunpckldq Vx,Hx,Wx (66),(v1)
5172 -63: packsswb Pq,Qq | vpacksswb Vx,Hx,Wx (66),(v1)
5173 -64: pcmpgtb Pq,Qq | vpcmpgtb Vx,Hx,Wx (66),(v1)
5174 -65: pcmpgtw Pq,Qq | vpcmpgtw Vx,Hx,Wx (66),(v1)
5175 -66: pcmpgtd Pq,Qq | vpcmpgtd Vx,Hx,Wx (66),(v1)
5176 -67: packuswb Pq,Qq | vpackuswb Vx,Hx,Wx (66),(v1)
5177 -68: punpckhbw Pq,Qd | vpunpckhbw Vx,Hx,Wx (66),(v1)
5178 -69: punpckhwd Pq,Qd | vpunpckhwd Vx,Hx,Wx (66),(v1)
5179 -6a: punpckhdq Pq,Qd | vpunpckhdq Vx,Hx,Wx (66),(v1)
5180 -6b: packssdw Pq,Qd | vpackssdw Vx,Hx,Wx (66),(v1)
5181 -6c: vpunpcklqdq Vx,Hx,Wx (66),(v1)
5182 -6d: vpunpckhqdq Vx,Hx,Wx (66),(v1)
5183 -6e: movd/q Pd,Ey | vmovd/q Vy,Ey (66),(v1)
5184 -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)
5185 -# 0x0f 0x70-0x7f
5186 -70: pshufw Pq,Qq,Ib | vpshufd Vx,Wx,Ib (66),(v1) | vpshufhw Vx,Wx,Ib (F3),(v1) | vpshuflw Vx,Wx,Ib (F2),(v1)
5187 -71: Grp12 (1A)
5188 -72: Grp13 (1A)
5189 -73: Grp14 (1A)
5190 -74: pcmpeqb Pq,Qq | vpcmpeqb Vx,Hx,Wx (66),(v1)
5191 -75: pcmpeqw Pq,Qq | vpcmpeqw Vx,Hx,Wx (66),(v1)
5192 -76: pcmpeqd Pq,Qq | vpcmpeqd Vx,Hx,Wx (66),(v1)
5193 -# Note: Remove (v), because vzeroall and vzeroupper becomes emms without VEX.
5194 -77: emms | vzeroupper | vzeroall
5195 -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)
5196 -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)
5197 -7a: vcvtudq2pd/uqq2pd Vpd,Wx (F3),(ev) | vcvtudq2ps/uqq2ps Vpd,Wx (F2),(ev) | vcvttps2qq/pd2qq Vx,Wx (66),(ev)
5198 -7b: vcvtusi2sd Vpd,Hpd,Ev (F2),(ev) | vcvtusi2ss Vps,Hps,Ev (F3),(ev) | vcvtps2qq/pd2qq Vx,Wx (66),(ev)
5199 -7c: vhaddpd Vpd,Hpd,Wpd (66) | vhaddps Vps,Hps,Wps (F2)
5200 -7d: vhsubpd Vpd,Hpd,Wpd (66) | vhsubps Vps,Hps,Wps (F2)
5201 -7e: movd/q Ey,Pd | vmovd/q Ey,Vy (66),(v1) | vmovq Vq,Wq (F3),(v1)
5202 -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)
5203 -# 0x0f 0x80-0x8f
5204 -# Note: "forced64" is Intel CPU behavior (see comment about CALL insn).
5205 -80: JO Jz (f64)
5206 -81: JNO Jz (f64)
5207 -82: JB/JC/JNAE Jz (f64)
5208 -83: JAE/JNB/JNC Jz (f64)
5209 -84: JE/JZ Jz (f64)
5210 -85: JNE/JNZ Jz (f64)
5211 -86: JBE/JNA Jz (f64)
5212 -87: JA/JNBE Jz (f64)
5213 -88: JS Jz (f64)
5214 -89: JNS Jz (f64)
5215 -8a: JP/JPE Jz (f64)
5216 -8b: JNP/JPO Jz (f64)
5217 -8c: JL/JNGE Jz (f64)
5218 -8d: JNL/JGE Jz (f64)
5219 -8e: JLE/JNG Jz (f64)
5220 -8f: JNLE/JG Jz (f64)
5221 -# 0x0f 0x90-0x9f
5222 -90: SETO Eb | kmovw/q Vk,Wk | kmovb/d Vk,Wk (66)
5223 -91: SETNO Eb | kmovw/q Mv,Vk | kmovb/d Mv,Vk (66)
5224 -92: SETB/C/NAE Eb | kmovw Vk,Rv | kmovb Vk,Rv (66) | kmovq/d Vk,Rv (F2)
5225 -93: SETAE/NB/NC Eb | kmovw Gv,Uk | kmovb Gv,Uk (66) | kmovq/d Gv,Uk (F2)
5226 -94: SETE/Z Eb
5227 -95: SETNE/NZ Eb
5228 -96: SETBE/NA Eb
5229 -97: SETA/NBE Eb
5230 -98: SETS Eb | kortestw/q Vk,Uk | kortestb/d Vk,Uk (66)
5231 -99: SETNS Eb | ktestw/q Vk,Uk | ktestb/d Vk,Uk (66)
5232 -9a: SETP/PE Eb
5233 -9b: SETNP/PO Eb
5234 -9c: SETL/NGE Eb
5235 -9d: SETNL/GE Eb
5236 -9e: SETLE/NG Eb
5237 -9f: SETNLE/G Eb
5238 -# 0x0f 0xa0-0xaf
5239 -a0: PUSH FS (d64)
5240 -a1: POP FS (d64)
5241 -a2: CPUID
5242 -a3: BT Ev,Gv
5243 -a4: SHLD Ev,Gv,Ib
5244 -a5: SHLD Ev,Gv,CL
5245 -a6: GrpPDLK
5246 -a7: GrpRNG
5247 -a8: PUSH GS (d64)
5248 -a9: POP GS (d64)
5249 -aa: RSM
5250 -ab: BTS Ev,Gv
5251 -ac: SHRD Ev,Gv,Ib
5252 -ad: SHRD Ev,Gv,CL
5253 -ae: Grp15 (1A),(1C)
5254 -af: IMUL Gv,Ev
5255 -# 0x0f 0xb0-0xbf
5256 -b0: CMPXCHG Eb,Gb
5257 -b1: CMPXCHG Ev,Gv
5258 -b2: LSS Gv,Mp
5259 -b3: BTR Ev,Gv
5260 -b4: LFS Gv,Mp
5261 -b5: LGS Gv,Mp
5262 -b6: MOVZX Gv,Eb
5263 -b7: MOVZX Gv,Ew
5264 -b8: JMPE (!F3) | POPCNT Gv,Ev (F3)
5265 -b9: Grp10 (1A)
5266 -ba: Grp8 Ev,Ib (1A)
5267 -bb: BTC Ev,Gv
5268 -bc: BSF Gv,Ev (!F3) | TZCNT Gv,Ev (F3)
5269 -bd: BSR Gv,Ev (!F3) | LZCNT Gv,Ev (F3)
5270 -be: MOVSX Gv,Eb
5271 -bf: MOVSX Gv,Ew
5272 -# 0x0f 0xc0-0xcf
5273 -c0: XADD Eb,Gb
5274 -c1: XADD Ev,Gv
5275 -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)
5276 -c3: movnti My,Gy
5277 -c4: pinsrw Pq,Ry/Mw,Ib | vpinsrw Vdq,Hdq,Ry/Mw,Ib (66),(v1)
5278 -c5: pextrw Gd,Nq,Ib | vpextrw Gd,Udq,Ib (66),(v1)
5279 -c6: vshufps Vps,Hps,Wps,Ib | vshufpd Vpd,Hpd,Wpd,Ib (66)
5280 -c7: Grp9 (1A)
5281 -c8: BSWAP RAX/EAX/R8/R8D
5282 -c9: BSWAP RCX/ECX/R9/R9D
5283 -ca: BSWAP RDX/EDX/R10/R10D
5284 -cb: BSWAP RBX/EBX/R11/R11D
5285 -cc: BSWAP RSP/ESP/R12/R12D
5286 -cd: BSWAP RBP/EBP/R13/R13D
5287 -ce: BSWAP RSI/ESI/R14/R14D
5288 -cf: BSWAP RDI/EDI/R15/R15D
5289 -# 0x0f 0xd0-0xdf
5290 -d0: vaddsubpd Vpd,Hpd,Wpd (66) | vaddsubps Vps,Hps,Wps (F2)
5291 -d1: psrlw Pq,Qq | vpsrlw Vx,Hx,Wx (66),(v1)
5292 -d2: psrld Pq,Qq | vpsrld Vx,Hx,Wx (66),(v1)
5293 -d3: psrlq Pq,Qq | vpsrlq Vx,Hx,Wx (66),(v1)
5294 -d4: paddq Pq,Qq | vpaddq Vx,Hx,Wx (66),(v1)
5295 -d5: pmullw Pq,Qq | vpmullw Vx,Hx,Wx (66),(v1)
5296 -d6: vmovq Wq,Vq (66),(v1) | movq2dq Vdq,Nq (F3) | movdq2q Pq,Uq (F2)
5297 -d7: pmovmskb Gd,Nq | vpmovmskb Gd,Ux (66),(v1)
5298 -d8: psubusb Pq,Qq | vpsubusb Vx,Hx,Wx (66),(v1)
5299 -d9: psubusw Pq,Qq | vpsubusw Vx,Hx,Wx (66),(v1)
5300 -da: pminub Pq,Qq | vpminub Vx,Hx,Wx (66),(v1)
5301 -db: pand Pq,Qq | vpand Vx,Hx,Wx (66),(v1) | vpandd/q Vx,Hx,Wx (66),(evo)
5302 -dc: paddusb Pq,Qq | vpaddusb Vx,Hx,Wx (66),(v1)
5303 -dd: paddusw Pq,Qq | vpaddusw Vx,Hx,Wx (66),(v1)
5304 -de: pmaxub Pq,Qq | vpmaxub Vx,Hx,Wx (66),(v1)
5305 -df: pandn Pq,Qq | vpandn Vx,Hx,Wx (66),(v1) | vpandnd/q Vx,Hx,Wx (66),(evo)
5306 -# 0x0f 0xe0-0xef
5307 -e0: pavgb Pq,Qq | vpavgb Vx,Hx,Wx (66),(v1)
5308 -e1: psraw Pq,Qq | vpsraw Vx,Hx,Wx (66),(v1)
5309 -e2: psrad Pq,Qq | vpsrad Vx,Hx,Wx (66),(v1)
5310 -e3: pavgw Pq,Qq | vpavgw Vx,Hx,Wx (66),(v1)
5311 -e4: pmulhuw Pq,Qq | vpmulhuw Vx,Hx,Wx (66),(v1)
5312 -e5: pmulhw Pq,Qq | vpmulhw Vx,Hx,Wx (66),(v1)
5313 -e6: vcvttpd2dq Vx,Wpd (66) | vcvtdq2pd Vx,Wdq (F3) | vcvtdq2pd/qq2pd Vx,Wdq (F3),(evo) | vcvtpd2dq Vx,Wpd (F2)
5314 -e7: movntq Mq,Pq | vmovntdq Mx,Vx (66)
5315 -e8: psubsb Pq,Qq | vpsubsb Vx,Hx,Wx (66),(v1)
5316 -e9: psubsw Pq,Qq | vpsubsw Vx,Hx,Wx (66),(v1)
5317 -ea: pminsw Pq,Qq | vpminsw Vx,Hx,Wx (66),(v1)
5318 -eb: por Pq,Qq | vpor Vx,Hx,Wx (66),(v1) | vpord/q Vx,Hx,Wx (66),(evo)
5319 -ec: paddsb Pq,Qq | vpaddsb Vx,Hx,Wx (66),(v1)
5320 -ed: paddsw Pq,Qq | vpaddsw Vx,Hx,Wx (66),(v1)
5321 -ee: pmaxsw Pq,Qq | vpmaxsw Vx,Hx,Wx (66),(v1)
5322 -ef: pxor Pq,Qq | vpxor Vx,Hx,Wx (66),(v1) | vpxord/q Vx,Hx,Wx (66),(evo)
5323 -# 0x0f 0xf0-0xff
5324 -f0: vlddqu Vx,Mx (F2)
5325 -f1: psllw Pq,Qq | vpsllw Vx,Hx,Wx (66),(v1)
5326 -f2: pslld Pq,Qq | vpslld Vx,Hx,Wx (66),(v1)
5327 -f3: psllq Pq,Qq | vpsllq Vx,Hx,Wx (66),(v1)
5328 -f4: pmuludq Pq,Qq | vpmuludq Vx,Hx,Wx (66),(v1)
5329 -f5: pmaddwd Pq,Qq | vpmaddwd Vx,Hx,Wx (66),(v1)
5330 -f6: psadbw Pq,Qq | vpsadbw Vx,Hx,Wx (66),(v1)
5331 -f7: maskmovq Pq,Nq | vmaskmovdqu Vx,Ux (66),(v1)
5332 -f8: psubb Pq,Qq | vpsubb Vx,Hx,Wx (66),(v1)
5333 -f9: psubw Pq,Qq | vpsubw Vx,Hx,Wx (66),(v1)
5334 -fa: psubd Pq,Qq | vpsubd Vx,Hx,Wx (66),(v1)
5335 -fb: psubq Pq,Qq | vpsubq Vx,Hx,Wx (66),(v1)
5336 -fc: paddb Pq,Qq | vpaddb Vx,Hx,Wx (66),(v1)
5337 -fd: paddw Pq,Qq | vpaddw Vx,Hx,Wx (66),(v1)
5338 -fe: paddd Pq,Qq | vpaddd Vx,Hx,Wx (66),(v1)
5339 -ff:
5340 -EndTable
5341 -
5342 -Table: 3-byte opcode 1 (0x0f 0x38)
5343 -Referrer: 3-byte escape 1
5344 -AVXcode: 2
5345 -# 0x0f 0x38 0x00-0x0f
5346 -00: pshufb Pq,Qq | vpshufb Vx,Hx,Wx (66),(v1)
5347 -01: phaddw Pq,Qq | vphaddw Vx,Hx,Wx (66),(v1)
5348 -02: phaddd Pq,Qq | vphaddd Vx,Hx,Wx (66),(v1)
5349 -03: phaddsw Pq,Qq | vphaddsw Vx,Hx,Wx (66),(v1)
5350 -04: pmaddubsw Pq,Qq | vpmaddubsw Vx,Hx,Wx (66),(v1)
5351 -05: phsubw Pq,Qq | vphsubw Vx,Hx,Wx (66),(v1)
5352 -06: phsubd Pq,Qq | vphsubd Vx,Hx,Wx (66),(v1)
5353 -07: phsubsw Pq,Qq | vphsubsw Vx,Hx,Wx (66),(v1)
5354 -08: psignb Pq,Qq | vpsignb Vx,Hx,Wx (66),(v1)
5355 -09: psignw Pq,Qq | vpsignw Vx,Hx,Wx (66),(v1)
5356 -0a: psignd Pq,Qq | vpsignd Vx,Hx,Wx (66),(v1)
5357 -0b: pmulhrsw Pq,Qq | vpmulhrsw Vx,Hx,Wx (66),(v1)
5358 -0c: vpermilps Vx,Hx,Wx (66),(v)
5359 -0d: vpermilpd Vx,Hx,Wx (66),(v)
5360 -0e: vtestps Vx,Wx (66),(v)
5361 -0f: vtestpd Vx,Wx (66),(v)
5362 -# 0x0f 0x38 0x10-0x1f
5363 -10: pblendvb Vdq,Wdq (66) | vpsrlvw Vx,Hx,Wx (66),(evo) | vpmovuswb Wx,Vx (F3),(ev)
5364 -11: vpmovusdb Wx,Vd (F3),(ev) | vpsravw Vx,Hx,Wx (66),(ev)
5365 -12: vpmovusqb Wx,Vq (F3),(ev) | vpsllvw Vx,Hx,Wx (66),(ev)
5366 -13: vcvtph2ps Vx,Wx (66),(v) | vpmovusdw Wx,Vd (F3),(ev)
5367 -14: blendvps Vdq,Wdq (66) | vpmovusqw Wx,Vq (F3),(ev) | vprorvd/q Vx,Hx,Wx (66),(evo)
5368 -15: blendvpd Vdq,Wdq (66) | vpmovusqd Wx,Vq (F3),(ev) | vprolvd/q Vx,Hx,Wx (66),(evo)
5369 -16: vpermps Vqq,Hqq,Wqq (66),(v) | vpermps/d Vqq,Hqq,Wqq (66),(evo)
5370 -17: vptest Vx,Wx (66)
5371 -18: vbroadcastss Vx,Wd (66),(v)
5372 -19: vbroadcastsd Vqq,Wq (66),(v) | vbroadcastf32x2 Vqq,Wq (66),(evo)
5373 -1a: vbroadcastf128 Vqq,Mdq (66),(v) | vbroadcastf32x4/64x2 Vqq,Wq (66),(evo)
5374 -1b: vbroadcastf32x8/64x4 Vqq,Mdq (66),(ev)
5375 -1c: pabsb Pq,Qq | vpabsb Vx,Wx (66),(v1)
5376 -1d: pabsw Pq,Qq | vpabsw Vx,Wx (66),(v1)
5377 -1e: pabsd Pq,Qq | vpabsd Vx,Wx (66),(v1)
5378 -1f: vpabsq Vx,Wx (66),(ev)
5379 -# 0x0f 0x38 0x20-0x2f
5380 -20: vpmovsxbw Vx,Ux/Mq (66),(v1) | vpmovswb Wx,Vx (F3),(ev)
5381 -21: vpmovsxbd Vx,Ux/Md (66),(v1) | vpmovsdb Wx,Vd (F3),(ev)
5382 -22: vpmovsxbq Vx,Ux/Mw (66),(v1) | vpmovsqb Wx,Vq (F3),(ev)
5383 -23: vpmovsxwd Vx,Ux/Mq (66),(v1) | vpmovsdw Wx,Vd (F3),(ev)
5384 -24: vpmovsxwq Vx,Ux/Md (66),(v1) | vpmovsqw Wx,Vq (F3),(ev)
5385 -25: vpmovsxdq Vx,Ux/Mq (66),(v1) | vpmovsqd Wx,Vq (F3),(ev)
5386 -26: vptestmb/w Vk,Hx,Wx (66),(ev) | vptestnmb/w Vk,Hx,Wx (F3),(ev)
5387 -27: vptestmd/q Vk,Hx,Wx (66),(ev) | vptestnmd/q Vk,Hx,Wx (F3),(ev)
5388 -28: vpmuldq Vx,Hx,Wx (66),(v1) | vpmovm2b/w Vx,Uk (F3),(ev)
5389 -29: vpcmpeqq Vx,Hx,Wx (66),(v1) | vpmovb2m/w2m Vk,Ux (F3),(ev)
5390 -2a: vmovntdqa Vx,Mx (66),(v1) | vpbroadcastmb2q Vx,Uk (F3),(ev)
5391 -2b: vpackusdw Vx,Hx,Wx (66),(v1)
5392 -2c: vmaskmovps Vx,Hx,Mx (66),(v) | vscalefps/d Vx,Hx,Wx (66),(evo)
5393 -2d: vmaskmovpd Vx,Hx,Mx (66),(v) | vscalefss/d Vx,Hx,Wx (66),(evo)
5394 -2e: vmaskmovps Mx,Hx,Vx (66),(v)
5395 -2f: vmaskmovpd Mx,Hx,Vx (66),(v)
5396 -# 0x0f 0x38 0x30-0x3f
5397 -30: vpmovzxbw Vx,Ux/Mq (66),(v1) | vpmovwb Wx,Vx (F3),(ev)
5398 -31: vpmovzxbd Vx,Ux/Md (66),(v1) | vpmovdb Wx,Vd (F3),(ev)
5399 -32: vpmovzxbq Vx,Ux/Mw (66),(v1) | vpmovqb Wx,Vq (F3),(ev)
5400 -33: vpmovzxwd Vx,Ux/Mq (66),(v1) | vpmovdw Wx,Vd (F3),(ev)
5401 -34: vpmovzxwq Vx,Ux/Md (66),(v1) | vpmovqw Wx,Vq (F3),(ev)
5402 -35: vpmovzxdq Vx,Ux/Mq (66),(v1) | vpmovqd Wx,Vq (F3),(ev)
5403 -36: vpermd Vqq,Hqq,Wqq (66),(v) | vpermd/q Vqq,Hqq,Wqq (66),(evo)
5404 -37: vpcmpgtq Vx,Hx,Wx (66),(v1)
5405 -38: vpminsb Vx,Hx,Wx (66),(v1) | vpmovm2d/q Vx,Uk (F3),(ev)
5406 -39: vpminsd Vx,Hx,Wx (66),(v1) | vpminsd/q Vx,Hx,Wx (66),(evo) | vpmovd2m/q2m Vk,Ux (F3),(ev)
5407 -3a: vpminuw Vx,Hx,Wx (66),(v1) | vpbroadcastmw2d Vx,Uk (F3),(ev)
5408 -3b: vpminud Vx,Hx,Wx (66),(v1) | vpminud/q Vx,Hx,Wx (66),(evo)
5409 -3c: vpmaxsb Vx,Hx,Wx (66),(v1)
5410 -3d: vpmaxsd Vx,Hx,Wx (66),(v1) | vpmaxsd/q Vx,Hx,Wx (66),(evo)
5411 -3e: vpmaxuw Vx,Hx,Wx (66),(v1)
5412 -3f: vpmaxud Vx,Hx,Wx (66),(v1) | vpmaxud/q Vx,Hx,Wx (66),(evo)
5413 -# 0x0f 0x38 0x40-0x8f
5414 -40: vpmulld Vx,Hx,Wx (66),(v1) | vpmulld/q Vx,Hx,Wx (66),(evo)
5415 -41: vphminposuw Vdq,Wdq (66),(v1)
5416 -42: vgetexpps/d Vx,Wx (66),(ev)
5417 -43: vgetexpss/d Vx,Hx,Wx (66),(ev)
5418 -44: vplzcntd/q Vx,Wx (66),(ev)
5419 -45: vpsrlvd/q Vx,Hx,Wx (66),(v)
5420 -46: vpsravd Vx,Hx,Wx (66),(v) | vpsravd/q Vx,Hx,Wx (66),(evo)
5421 -47: vpsllvd/q Vx,Hx,Wx (66),(v)
5422 -# Skip 0x48-0x4b
5423 -4c: vrcp14ps/d Vpd,Wpd (66),(ev)
5424 -4d: vrcp14ss/d Vsd,Hpd,Wsd (66),(ev)
5425 -4e: vrsqrt14ps/d Vpd,Wpd (66),(ev)
5426 -4f: vrsqrt14ss/d Vsd,Hsd,Wsd (66),(ev)
5427 -# Skip 0x50-0x57
5428 -58: vpbroadcastd Vx,Wx (66),(v)
5429 -59: vpbroadcastq Vx,Wx (66),(v) | vbroadcasti32x2 Vx,Wx (66),(evo)
5430 -5a: vbroadcasti128 Vqq,Mdq (66),(v) | vbroadcasti32x4/64x2 Vx,Wx (66),(evo)
5431 -5b: vbroadcasti32x8/64x4 Vqq,Mdq (66),(ev)
5432 -# Skip 0x5c-0x63
5433 -64: vpblendmd/q Vx,Hx,Wx (66),(ev)
5434 -65: vblendmps/d Vx,Hx,Wx (66),(ev)
5435 -66: vpblendmb/w Vx,Hx,Wx (66),(ev)
5436 -# Skip 0x67-0x74
5437 -75: vpermi2b/w Vx,Hx,Wx (66),(ev)
5438 -76: vpermi2d/q Vx,Hx,Wx (66),(ev)
5439 -77: vpermi2ps/d Vx,Hx,Wx (66),(ev)
5440 -78: vpbroadcastb Vx,Wx (66),(v)
5441 -79: vpbroadcastw Vx,Wx (66),(v)
5442 -7a: vpbroadcastb Vx,Rv (66),(ev)
5443 -7b: vpbroadcastw Vx,Rv (66),(ev)
5444 -7c: vpbroadcastd/q Vx,Rv (66),(ev)
5445 -7d: vpermt2b/w Vx,Hx,Wx (66),(ev)
5446 -7e: vpermt2d/q Vx,Hx,Wx (66),(ev)
5447 -7f: vpermt2ps/d Vx,Hx,Wx (66),(ev)
5448 -80: INVEPT Gy,Mdq (66)
5449 -81: INVPID Gy,Mdq (66)
5450 -82: INVPCID Gy,Mdq (66)
5451 -83: vpmultishiftqb Vx,Hx,Wx (66),(ev)
5452 -88: vexpandps/d Vpd,Wpd (66),(ev)
5453 -89: vpexpandd/q Vx,Wx (66),(ev)
5454 -8a: vcompressps/d Wx,Vx (66),(ev)
5455 -8b: vpcompressd/q Wx,Vx (66),(ev)
5456 -8c: vpmaskmovd/q Vx,Hx,Mx (66),(v)
5457 -8d: vpermb/w Vx,Hx,Wx (66),(ev)
5458 -8e: vpmaskmovd/q Mx,Vx,Hx (66),(v)
5459 -# 0x0f 0x38 0x90-0xbf (FMA)
5460 -90: vgatherdd/q Vx,Hx,Wx (66),(v) | vpgatherdd/q Vx,Wx (66),(evo)
5461 -91: vgatherqd/q Vx,Hx,Wx (66),(v) | vpgatherqd/q Vx,Wx (66),(evo)
5462 -92: vgatherdps/d Vx,Hx,Wx (66),(v)
5463 -93: vgatherqps/d Vx,Hx,Wx (66),(v)
5464 -94:
5465 -95:
5466 -96: vfmaddsub132ps/d Vx,Hx,Wx (66),(v)
5467 -97: vfmsubadd132ps/d Vx,Hx,Wx (66),(v)
5468 -98: vfmadd132ps/d Vx,Hx,Wx (66),(v)
5469 -99: vfmadd132ss/d Vx,Hx,Wx (66),(v),(v1)
5470 -9a: vfmsub132ps/d Vx,Hx,Wx (66),(v)
5471 -9b: vfmsub132ss/d Vx,Hx,Wx (66),(v),(v1)
5472 -9c: vfnmadd132ps/d Vx,Hx,Wx (66),(v)
5473 -9d: vfnmadd132ss/d Vx,Hx,Wx (66),(v),(v1)
5474 -9e: vfnmsub132ps/d Vx,Hx,Wx (66),(v)
5475 -9f: vfnmsub132ss/d Vx,Hx,Wx (66),(v),(v1)
5476 -a0: vpscatterdd/q Wx,Vx (66),(ev)
5477 -a1: vpscatterqd/q Wx,Vx (66),(ev)
5478 -a2: vscatterdps/d Wx,Vx (66),(ev)
5479 -a3: vscatterqps/d Wx,Vx (66),(ev)
5480 -a6: vfmaddsub213ps/d Vx,Hx,Wx (66),(v)
5481 -a7: vfmsubadd213ps/d Vx,Hx,Wx (66),(v)
5482 -a8: vfmadd213ps/d Vx,Hx,Wx (66),(v)
5483 -a9: vfmadd213ss/d Vx,Hx,Wx (66),(v),(v1)
5484 -aa: vfmsub213ps/d Vx,Hx,Wx (66),(v)
5485 -ab: vfmsub213ss/d Vx,Hx,Wx (66),(v),(v1)
5486 -ac: vfnmadd213ps/d Vx,Hx,Wx (66),(v)
5487 -ad: vfnmadd213ss/d Vx,Hx,Wx (66),(v),(v1)
5488 -ae: vfnmsub213ps/d Vx,Hx,Wx (66),(v)
5489 -af: vfnmsub213ss/d Vx,Hx,Wx (66),(v),(v1)
5490 -b4: vpmadd52luq Vx,Hx,Wx (66),(ev)
5491 -b5: vpmadd52huq Vx,Hx,Wx (66),(ev)
5492 -b6: vfmaddsub231ps/d Vx,Hx,Wx (66),(v)
5493 -b7: vfmsubadd231ps/d Vx,Hx,Wx (66),(v)
5494 -b8: vfmadd231ps/d Vx,Hx,Wx (66),(v)
5495 -b9: vfmadd231ss/d Vx,Hx,Wx (66),(v),(v1)
5496 -ba: vfmsub231ps/d Vx,Hx,Wx (66),(v)
5497 -bb: vfmsub231ss/d Vx,Hx,Wx (66),(v),(v1)
5498 -bc: vfnmadd231ps/d Vx,Hx,Wx (66),(v)
5499 -bd: vfnmadd231ss/d Vx,Hx,Wx (66),(v),(v1)
5500 -be: vfnmsub231ps/d Vx,Hx,Wx (66),(v)
5501 -bf: vfnmsub231ss/d Vx,Hx,Wx (66),(v),(v1)
5502 -# 0x0f 0x38 0xc0-0xff
5503 -c4: vpconflictd/q Vx,Wx (66),(ev)
5504 -c6: Grp18 (1A)
5505 -c7: Grp19 (1A)
5506 -c8: sha1nexte Vdq,Wdq | vexp2ps/d Vx,Wx (66),(ev)
5507 -c9: sha1msg1 Vdq,Wdq
5508 -ca: sha1msg2 Vdq,Wdq | vrcp28ps/d Vx,Wx (66),(ev)
5509 -cb: sha256rnds2 Vdq,Wdq | vrcp28ss/d Vx,Hx,Wx (66),(ev)
5510 -cc: sha256msg1 Vdq,Wdq | vrsqrt28ps/d Vx,Wx (66),(ev)
5511 -cd: sha256msg2 Vdq,Wdq | vrsqrt28ss/d Vx,Hx,Wx (66),(ev)
5512 -db: VAESIMC Vdq,Wdq (66),(v1)
5513 -dc: VAESENC Vdq,Hdq,Wdq (66),(v1)
5514 -dd: VAESENCLAST Vdq,Hdq,Wdq (66),(v1)
5515 -de: VAESDEC Vdq,Hdq,Wdq (66),(v1)
5516 -df: VAESDECLAST Vdq,Hdq,Wdq (66),(v1)
5517 -f0: MOVBE Gy,My | MOVBE Gw,Mw (66) | CRC32 Gd,Eb (F2) | CRC32 Gd,Eb (66&F2)
5518 -f1: MOVBE My,Gy | MOVBE Mw,Gw (66) | CRC32 Gd,Ey (F2) | CRC32 Gd,Ew (66&F2)
5519 -f2: ANDN Gy,By,Ey (v)
5520 -f3: Grp17 (1A)
5521 -f5: BZHI Gy,Ey,By (v) | PEXT Gy,By,Ey (F3),(v) | PDEP Gy,By,Ey (F2),(v)
5522 -f6: ADCX Gy,Ey (66) | ADOX Gy,Ey (F3) | MULX By,Gy,rDX,Ey (F2),(v)
5523 -f7: BEXTR Gy,Ey,By (v) | SHLX Gy,Ey,By (66),(v) | SARX Gy,Ey,By (F3),(v) | SHRX Gy,Ey,By (F2),(v)
5524 -EndTable
5525 -
5526 -Table: 3-byte opcode 2 (0x0f 0x3a)
5527 -Referrer: 3-byte escape 2
5528 -AVXcode: 3
5529 -# 0x0f 0x3a 0x00-0xff
5530 -00: vpermq Vqq,Wqq,Ib (66),(v)
5531 -01: vpermpd Vqq,Wqq,Ib (66),(v)
5532 -02: vpblendd Vx,Hx,Wx,Ib (66),(v)
5533 -03: valignd/q Vx,Hx,Wx,Ib (66),(ev)
5534 -04: vpermilps Vx,Wx,Ib (66),(v)
5535 -05: vpermilpd Vx,Wx,Ib (66),(v)
5536 -06: vperm2f128 Vqq,Hqq,Wqq,Ib (66),(v)
5537 -07:
5538 -08: vroundps Vx,Wx,Ib (66) | vrndscaleps Vx,Wx,Ib (66),(evo)
5539 -09: vroundpd Vx,Wx,Ib (66) | vrndscalepd Vx,Wx,Ib (66),(evo)
5540 -0a: vroundss Vss,Wss,Ib (66),(v1) | vrndscaless Vx,Hx,Wx,Ib (66),(evo)
5541 -0b: vroundsd Vsd,Wsd,Ib (66),(v1) | vrndscalesd Vx,Hx,Wx,Ib (66),(evo)
5542 -0c: vblendps Vx,Hx,Wx,Ib (66)
5543 -0d: vblendpd Vx,Hx,Wx,Ib (66)
5544 -0e: vpblendw Vx,Hx,Wx,Ib (66),(v1)
5545 -0f: palignr Pq,Qq,Ib | vpalignr Vx,Hx,Wx,Ib (66),(v1)
5546 -14: vpextrb Rd/Mb,Vdq,Ib (66),(v1)
5547 -15: vpextrw Rd/Mw,Vdq,Ib (66),(v1)
5548 -16: vpextrd/q Ey,Vdq,Ib (66),(v1)
5549 -17: vextractps Ed,Vdq,Ib (66),(v1)
5550 -18: vinsertf128 Vqq,Hqq,Wqq,Ib (66),(v) | vinsertf32x4/64x2 Vqq,Hqq,Wqq,Ib (66),(evo)
5551 -19: vextractf128 Wdq,Vqq,Ib (66),(v) | vextractf32x4/64x2 Wdq,Vqq,Ib (66),(evo)
5552 -1a: vinsertf32x8/64x4 Vqq,Hqq,Wqq,Ib (66),(ev)
5553 -1b: vextractf32x8/64x4 Wdq,Vqq,Ib (66),(ev)
5554 -1d: vcvtps2ph Wx,Vx,Ib (66),(v)
5555 -1e: vpcmpud/q Vk,Hd,Wd,Ib (66),(ev)
5556 -1f: vpcmpd/q Vk,Hd,Wd,Ib (66),(ev)
5557 -20: vpinsrb Vdq,Hdq,Ry/Mb,Ib (66),(v1)
5558 -21: vinsertps Vdq,Hdq,Udq/Md,Ib (66),(v1)
5559 -22: vpinsrd/q Vdq,Hdq,Ey,Ib (66),(v1)
5560 -23: vshuff32x4/64x2 Vx,Hx,Wx,Ib (66),(ev)
5561 -25: vpternlogd/q Vx,Hx,Wx,Ib (66),(ev)
5562 -26: vgetmantps/d Vx,Wx,Ib (66),(ev)
5563 -27: vgetmantss/d Vx,Hx,Wx,Ib (66),(ev)
5564 -30: kshiftrb/w Vk,Uk,Ib (66),(v)
5565 -31: kshiftrd/q Vk,Uk,Ib (66),(v)
5566 -32: kshiftlb/w Vk,Uk,Ib (66),(v)
5567 -33: kshiftld/q Vk,Uk,Ib (66),(v)
5568 -38: vinserti128 Vqq,Hqq,Wqq,Ib (66),(v) | vinserti32x4/64x2 Vqq,Hqq,Wqq,Ib (66),(evo)
5569 -39: vextracti128 Wdq,Vqq,Ib (66),(v) | vextracti32x4/64x2 Wdq,Vqq,Ib (66),(evo)
5570 -3a: vinserti32x8/64x4 Vqq,Hqq,Wqq,Ib (66),(ev)
5571 -3b: vextracti32x8/64x4 Wdq,Vqq,Ib (66),(ev)
5572 -3e: vpcmpub/w Vk,Hk,Wx,Ib (66),(ev)
5573 -3f: vpcmpb/w Vk,Hk,Wx,Ib (66),(ev)
5574 -40: vdpps Vx,Hx,Wx,Ib (66)
5575 -41: vdppd Vdq,Hdq,Wdq,Ib (66),(v1)
5576 -42: vmpsadbw Vx,Hx,Wx,Ib (66),(v1) | vdbpsadbw Vx,Hx,Wx,Ib (66),(evo)
5577 -43: vshufi32x4/64x2 Vx,Hx,Wx,Ib (66),(ev)
5578 -44: vpclmulqdq Vdq,Hdq,Wdq,Ib (66),(v1)
5579 -46: vperm2i128 Vqq,Hqq,Wqq,Ib (66),(v)
5580 -4a: vblendvps Vx,Hx,Wx,Lx (66),(v)
5581 -4b: vblendvpd Vx,Hx,Wx,Lx (66),(v)
5582 -4c: vpblendvb Vx,Hx,Wx,Lx (66),(v1)
5583 -50: vrangeps/d Vx,Hx,Wx,Ib (66),(ev)
5584 -51: vrangess/d Vx,Hx,Wx,Ib (66),(ev)
5585 -54: vfixupimmps/d Vx,Hx,Wx,Ib (66),(ev)
5586 -55: vfixupimmss/d Vx,Hx,Wx,Ib (66),(ev)
5587 -56: vreduceps/d Vx,Wx,Ib (66),(ev)
5588 -57: vreducess/d Vx,Hx,Wx,Ib (66),(ev)
5589 -60: vpcmpestrm Vdq,Wdq,Ib (66),(v1)
5590 -61: vpcmpestri Vdq,Wdq,Ib (66),(v1)
5591 -62: vpcmpistrm Vdq,Wdq,Ib (66),(v1)
5592 -63: vpcmpistri Vdq,Wdq,Ib (66),(v1)
5593 -66: vfpclassps/d Vk,Wx,Ib (66),(ev)
5594 -67: vfpclassss/d Vk,Wx,Ib (66),(ev)
5595 -cc: sha1rnds4 Vdq,Wdq,Ib
5596 -df: VAESKEYGEN Vdq,Wdq,Ib (66),(v1)
5597 -f0: RORX Gy,Ey,Ib (F2),(v)
5598 -EndTable
5599 -
5600 -GrpTable: Grp1
5601 -0: ADD
5602 -1: OR
5603 -2: ADC
5604 -3: SBB
5605 -4: AND
5606 -5: SUB
5607 -6: XOR
5608 -7: CMP
5609 -EndTable
5610 -
5611 -GrpTable: Grp1A
5612 -0: POP
5613 -EndTable
5614 -
5615 -GrpTable: Grp2
5616 -0: ROL
5617 -1: ROR
5618 -2: RCL
5619 -3: RCR
5620 -4: SHL/SAL
5621 -5: SHR
5622 -6:
5623 -7: SAR
5624 -EndTable
5625 -
5626 -GrpTable: Grp3_1
5627 -0: TEST Eb,Ib
5628 -1: TEST Eb,Ib
5629 -2: NOT Eb
5630 -3: NEG Eb
5631 -4: MUL AL,Eb
5632 -5: IMUL AL,Eb
5633 -6: DIV AL,Eb
5634 -7: IDIV AL,Eb
5635 -EndTable
5636 -
5637 -GrpTable: Grp3_2
5638 -0: TEST Ev,Iz
5639 -1:
5640 -2: NOT Ev
5641 -3: NEG Ev
5642 -4: MUL rAX,Ev
5643 -5: IMUL rAX,Ev
5644 -6: DIV rAX,Ev
5645 -7: IDIV rAX,Ev
5646 -EndTable
5647 -
5648 -GrpTable: Grp4
5649 -0: INC Eb
5650 -1: DEC Eb
5651 -EndTable
5652 -
5653 -GrpTable: Grp5
5654 -0: INC Ev
5655 -1: DEC Ev
5656 -# Note: "forced64" is Intel CPU behavior (see comment about CALL insn).
5657 -2: CALLN Ev (f64)
5658 -3: CALLF Ep
5659 -4: JMPN Ev (f64)
5660 -5: JMPF Mp
5661 -6: PUSH Ev (d64)
5662 -7:
5663 -EndTable
5664 -
5665 -GrpTable: Grp6
5666 -0: SLDT Rv/Mw
5667 -1: STR Rv/Mw
5668 -2: LLDT Ew
5669 -3: LTR Ew
5670 -4: VERR Ew
5671 -5: VERW Ew
5672 -EndTable
5673 -
5674 -GrpTable: Grp7
5675 -0: SGDT Ms | VMCALL (001),(11B) | VMLAUNCH (010),(11B) | VMRESUME (011),(11B) | VMXOFF (100),(11B)
5676 -1: SIDT Ms | MONITOR (000),(11B) | MWAIT (001),(11B) | CLAC (010),(11B) | STAC (011),(11B)
5677 -2: LGDT Ms | XGETBV (000),(11B) | XSETBV (001),(11B) | VMFUNC (100),(11B) | XEND (101)(11B) | XTEST (110)(11B)
5678 -3: LIDT Ms
5679 -4: SMSW Mw/Rv
5680 -5: rdpkru (110),(11B) | wrpkru (111),(11B)
5681 -6: LMSW Ew
5682 -7: INVLPG Mb | SWAPGS (o64),(000),(11B) | RDTSCP (001),(11B)
5683 -EndTable
5684 -
5685 -GrpTable: Grp8
5686 -4: BT
5687 -5: BTS
5688 -6: BTR
5689 -7: BTC
5690 -EndTable
5691 -
5692 -GrpTable: Grp9
5693 -1: CMPXCHG8B/16B Mq/Mdq
5694 -3: xrstors
5695 -4: xsavec
5696 -5: xsaves
5697 -6: VMPTRLD Mq | VMCLEAR Mq (66) | VMXON Mq (F3) | RDRAND Rv (11B)
5698 -7: VMPTRST Mq | VMPTRST Mq (F3) | RDSEED Rv (11B)
5699 -EndTable
5700 -
5701 -GrpTable: Grp10
5702 -EndTable
5703 -
5704 -# Grp11A and Grp11B are expressed as Grp11 in Intel SDM
5705 -GrpTable: Grp11A
5706 -0: MOV Eb,Ib
5707 -7: XABORT Ib (000),(11B)
5708 -EndTable
5709 -
5710 -GrpTable: Grp11B
5711 -0: MOV Eb,Iz
5712 -7: XBEGIN Jz (000),(11B)
5713 -EndTable
5714 -
5715 -GrpTable: Grp12
5716 -2: psrlw Nq,Ib (11B) | vpsrlw Hx,Ux,Ib (66),(11B),(v1)
5717 -4: psraw Nq,Ib (11B) | vpsraw Hx,Ux,Ib (66),(11B),(v1)
5718 -6: psllw Nq,Ib (11B) | vpsllw Hx,Ux,Ib (66),(11B),(v1)
5719 -EndTable
5720 -
5721 -GrpTable: Grp13
5722 -0: vprord/q Hx,Wx,Ib (66),(ev)
5723 -1: vprold/q Hx,Wx,Ib (66),(ev)
5724 -2: psrld Nq,Ib (11B) | vpsrld Hx,Ux,Ib (66),(11B),(v1)
5725 -4: psrad Nq,Ib (11B) | vpsrad Hx,Ux,Ib (66),(11B),(v1) | vpsrad/q Hx,Ux,Ib (66),(evo)
5726 -6: pslld Nq,Ib (11B) | vpslld Hx,Ux,Ib (66),(11B),(v1)
5727 -EndTable
5728 -
5729 -GrpTable: Grp14
5730 -2: psrlq Nq,Ib (11B) | vpsrlq Hx,Ux,Ib (66),(11B),(v1)
5731 -3: vpsrldq Hx,Ux,Ib (66),(11B),(v1)
5732 -6: psllq Nq,Ib (11B) | vpsllq Hx,Ux,Ib (66),(11B),(v1)
5733 -7: vpslldq Hx,Ux,Ib (66),(11B),(v1)
5734 -EndTable
5735 -
5736 -GrpTable: Grp15
5737 -0: fxsave | RDFSBASE Ry (F3),(11B)
5738 -1: fxstor | RDGSBASE Ry (F3),(11B)
5739 -2: vldmxcsr Md (v1) | WRFSBASE Ry (F3),(11B)
5740 -3: vstmxcsr Md (v1) | WRGSBASE Ry (F3),(11B)
5741 -4: XSAVE
5742 -5: XRSTOR | lfence (11B)
5743 -6: XSAVEOPT | clwb (66) | mfence (11B)
5744 -7: clflush | clflushopt (66) | sfence (11B)
5745 -EndTable
5746 -
5747 -GrpTable: Grp16
5748 -0: prefetch NTA
5749 -1: prefetch T0
5750 -2: prefetch T1
5751 -3: prefetch T2
5752 -EndTable
5753 -
5754 -GrpTable: Grp17
5755 -1: BLSR By,Ey (v)
5756 -2: BLSMSK By,Ey (v)
5757 -3: BLSI By,Ey (v)
5758 -EndTable
5759 -
5760 -GrpTable: Grp18
5761 -1: vgatherpf0dps/d Wx (66),(ev)
5762 -2: vgatherpf1dps/d Wx (66),(ev)
5763 -5: vscatterpf0dps/d Wx (66),(ev)
5764 -6: vscatterpf1dps/d Wx (66),(ev)
5765 -EndTable
5766 -
5767 -GrpTable: Grp19
5768 -1: vgatherpf0qps/d Wx (66),(ev)
5769 -2: vgatherpf1qps/d Wx (66),(ev)
5770 -5: vscatterpf0qps/d Wx (66),(ev)
5771 -6: vscatterpf1qps/d Wx (66),(ev)
5772 -EndTable
5773 -
5774 -# AMD's Prefetch Group
5775 -GrpTable: GrpP
5776 -0: PREFETCH
5777 -1: PREFETCHW
5778 -EndTable
5779 -
5780 -GrpTable: GrpPDLK
5781 -0: MONTMUL
5782 -1: XSHA1
5783 -2: XSHA2
5784 -EndTable
5785 -
5786 -GrpTable: GrpRNG
5787 -0: xstore-rng
5788 -1: xcrypt-ecb
5789 -2: xcrypt-cbc
5790 -4: xcrypt-cfb
5791 -5: xcrypt-ofb
5792 -EndTable
5793 diff --git a/tools/objtool/arch/x86/lib/inat.c b/tools/objtool/arch/x86/lib/inat.c
5794 new file mode 100644
5795 index 000000000000..c1f01a8e9f65
5796 --- /dev/null
5797 +++ b/tools/objtool/arch/x86/lib/inat.c
5798 @@ -0,0 +1,97 @@
5799 +/*
5800 + * x86 instruction attribute tables
5801 + *
5802 + * Written by Masami Hiramatsu <mhiramat@redhat.com>
5803 + *
5804 + * This program is free software; you can redistribute it and/or modify
5805 + * it under the terms of the GNU General Public License as published by
5806 + * the Free Software Foundation; either version 2 of the License, or
5807 + * (at your option) any later version.
5808 + *
5809 + * This program is distributed in the hope that it will be useful,
5810 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
5811 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5812 + * GNU General Public License for more details.
5813 + *
5814 + * You should have received a copy of the GNU General Public License
5815 + * along with this program; if not, write to the Free Software
5816 + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
5817 + *
5818 + */
5819 +#include <asm/insn.h>
5820 +
5821 +/* Attribute tables are generated from opcode map */
5822 +#include "inat-tables.c"
5823 +
5824 +/* Attribute search APIs */
5825 +insn_attr_t inat_get_opcode_attribute(insn_byte_t opcode)
5826 +{
5827 + return inat_primary_table[opcode];
5828 +}
5829 +
5830 +int inat_get_last_prefix_id(insn_byte_t last_pfx)
5831 +{
5832 + insn_attr_t lpfx_attr;
5833 +
5834 + lpfx_attr = inat_get_opcode_attribute(last_pfx);
5835 + return inat_last_prefix_id(lpfx_attr);
5836 +}
5837 +
5838 +insn_attr_t inat_get_escape_attribute(insn_byte_t opcode, int lpfx_id,
5839 + insn_attr_t esc_attr)
5840 +{
5841 + const insn_attr_t *table;
5842 + int n;
5843 +
5844 + n = inat_escape_id(esc_attr);
5845 +
5846 + table = inat_escape_tables[n][0];
5847 + if (!table)
5848 + return 0;
5849 + if (inat_has_variant(table[opcode]) && lpfx_id) {
5850 + table = inat_escape_tables[n][lpfx_id];
5851 + if (!table)
5852 + return 0;
5853 + }
5854 + return table[opcode];
5855 +}
5856 +
5857 +insn_attr_t inat_get_group_attribute(insn_byte_t modrm, int lpfx_id,
5858 + insn_attr_t grp_attr)
5859 +{
5860 + const insn_attr_t *table;
5861 + int n;
5862 +
5863 + n = inat_group_id(grp_attr);
5864 +
5865 + table = inat_group_tables[n][0];
5866 + if (!table)
5867 + return inat_group_common_attribute(grp_attr);
5868 + if (inat_has_variant(table[X86_MODRM_REG(modrm)]) && lpfx_id) {
5869 + table = inat_group_tables[n][lpfx_id];
5870 + if (!table)
5871 + return inat_group_common_attribute(grp_attr);
5872 + }
5873 + return table[X86_MODRM_REG(modrm)] |
5874 + inat_group_common_attribute(grp_attr);
5875 +}
5876 +
5877 +insn_attr_t inat_get_avx_attribute(insn_byte_t opcode, insn_byte_t vex_m,
5878 + insn_byte_t vex_p)
5879 +{
5880 + const insn_attr_t *table;
5881 + if (vex_m > X86_VEX_M_MAX || vex_p > INAT_LSTPFX_MAX)
5882 + return 0;
5883 + /* At first, this checks the master table */
5884 + table = inat_avx_tables[vex_m][0];
5885 + if (!table)
5886 + return 0;
5887 + if (!inat_is_group(table[opcode]) && vex_p) {
5888 + /* If this is not a group, get attribute directly */
5889 + table = inat_avx_tables[vex_m][vex_p];
5890 + if (!table)
5891 + return 0;
5892 + }
5893 + return table[opcode];
5894 +}
5895 +
5896 diff --git a/tools/objtool/arch/x86/lib/insn.c b/tools/objtool/arch/x86/lib/insn.c
5897 new file mode 100644
5898 index 000000000000..1088eb8f3a5f
5899 --- /dev/null
5900 +++ b/tools/objtool/arch/x86/lib/insn.c
5901 @@ -0,0 +1,606 @@
5902 +/*
5903 + * x86 instruction analysis
5904 + *
5905 + * This program is free software; you can redistribute it and/or modify
5906 + * it under the terms of the GNU General Public License as published by
5907 + * the Free Software Foundation; either version 2 of the License, or
5908 + * (at your option) any later version.
5909 + *
5910 + * This program is distributed in the hope that it will be useful,
5911 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
5912 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5913 + * GNU General Public License for more details.
5914 + *
5915 + * You should have received a copy of the GNU General Public License
5916 + * along with this program; if not, write to the Free Software
5917 + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
5918 + *
5919 + * Copyright (C) IBM Corporation, 2002, 2004, 2009
5920 + */
5921 +
5922 +#ifdef __KERNEL__
5923 +#include <linux/string.h>
5924 +#else
5925 +#include <string.h>
5926 +#endif
5927 +#include <asm/inat.h>
5928 +#include <asm/insn.h>
5929 +
5930 +/* Verify next sizeof(t) bytes can be on the same instruction */
5931 +#define validate_next(t, insn, n) \
5932 + ((insn)->next_byte + sizeof(t) + n <= (insn)->end_kaddr)
5933 +
5934 +#define __get_next(t, insn) \
5935 + ({ t r = *(t*)insn->next_byte; insn->next_byte += sizeof(t); r; })
5936 +
5937 +#define __peek_nbyte_next(t, insn, n) \
5938 + ({ t r = *(t*)((insn)->next_byte + n); r; })
5939 +
5940 +#define get_next(t, insn) \
5941 + ({ if (unlikely(!validate_next(t, insn, 0))) goto err_out; __get_next(t, insn); })
5942 +
5943 +#define peek_nbyte_next(t, insn, n) \
5944 + ({ if (unlikely(!validate_next(t, insn, n))) goto err_out; __peek_nbyte_next(t, insn, n); })
5945 +
5946 +#define peek_next(t, insn) peek_nbyte_next(t, insn, 0)
5947 +
5948 +/**
5949 + * insn_init() - initialize struct insn
5950 + * @insn: &struct insn to be initialized
5951 + * @kaddr: address (in kernel memory) of instruction (or copy thereof)
5952 + * @x86_64: !0 for 64-bit kernel or 64-bit app
5953 + */
5954 +void insn_init(struct insn *insn, const void *kaddr, int buf_len, int x86_64)
5955 +{
5956 + /*
5957 + * Instructions longer than MAX_INSN_SIZE (15 bytes) are invalid
5958 + * even if the input buffer is long enough to hold them.
5959 + */
5960 + if (buf_len > MAX_INSN_SIZE)
5961 + buf_len = MAX_INSN_SIZE;
5962 +
5963 + memset(insn, 0, sizeof(*insn));
5964 + insn->kaddr = kaddr;
5965 + insn->end_kaddr = kaddr + buf_len;
5966 + insn->next_byte = kaddr;
5967 + insn->x86_64 = x86_64 ? 1 : 0;
5968 + insn->opnd_bytes = 4;
5969 + if (x86_64)
5970 + insn->addr_bytes = 8;
5971 + else
5972 + insn->addr_bytes = 4;
5973 +}
5974 +
5975 +/**
5976 + * insn_get_prefixes - scan x86 instruction prefix bytes
5977 + * @insn: &struct insn containing instruction
5978 + *
5979 + * Populates the @insn->prefixes bitmap, and updates @insn->next_byte
5980 + * to point to the (first) opcode. No effect if @insn->prefixes.got
5981 + * is already set.
5982 + */
5983 +void insn_get_prefixes(struct insn *insn)
5984 +{
5985 + struct insn_field *prefixes = &insn->prefixes;
5986 + insn_attr_t attr;
5987 + insn_byte_t b, lb;
5988 + int i, nb;
5989 +
5990 + if (prefixes->got)
5991 + return;
5992 +
5993 + nb = 0;
5994 + lb = 0;
5995 + b = peek_next(insn_byte_t, insn);
5996 + attr = inat_get_opcode_attribute(b);
5997 + while (inat_is_legacy_prefix(attr)) {
5998 + /* Skip if same prefix */
5999 + for (i = 0; i < nb; i++)
6000 + if (prefixes->bytes[i] == b)
6001 + goto found;
6002 + if (nb == 4)
6003 + /* Invalid instruction */
6004 + break;
6005 + prefixes->bytes[nb++] = b;
6006 + if (inat_is_address_size_prefix(attr)) {
6007 + /* address size switches 2/4 or 4/8 */
6008 + if (insn->x86_64)
6009 + insn->addr_bytes ^= 12;
6010 + else
6011 + insn->addr_bytes ^= 6;
6012 + } else if (inat_is_operand_size_prefix(attr)) {
6013 + /* oprand size switches 2/4 */
6014 + insn->opnd_bytes ^= 6;
6015 + }
6016 +found:
6017 + prefixes->nbytes++;
6018 + insn->next_byte++;
6019 + lb = b;
6020 + b = peek_next(insn_byte_t, insn);
6021 + attr = inat_get_opcode_attribute(b);
6022 + }
6023 + /* Set the last prefix */
6024 + if (lb && lb != insn->prefixes.bytes[3]) {
6025 + if (unlikely(insn->prefixes.bytes[3])) {
6026 + /* Swap the last prefix */
6027 + b = insn->prefixes.bytes[3];
6028 + for (i = 0; i < nb; i++)
6029 + if (prefixes->bytes[i] == lb)
6030 + prefixes->bytes[i] = b;
6031 + }
6032 + insn->prefixes.bytes[3] = lb;
6033 + }
6034 +
6035 + /* Decode REX prefix */
6036 + if (insn->x86_64) {
6037 + b = peek_next(insn_byte_t, insn);
6038 + attr = inat_get_opcode_attribute(b);
6039 + if (inat_is_rex_prefix(attr)) {
6040 + insn->rex_prefix.value = b;
6041 + insn->rex_prefix.nbytes = 1;
6042 + insn->next_byte++;
6043 + if (X86_REX_W(b))
6044 + /* REX.W overrides opnd_size */
6045 + insn->opnd_bytes = 8;
6046 + }
6047 + }
6048 + insn->rex_prefix.got = 1;
6049 +
6050 + /* Decode VEX prefix */
6051 + b = peek_next(insn_byte_t, insn);
6052 + attr = inat_get_opcode_attribute(b);
6053 + if (inat_is_vex_prefix(attr)) {
6054 + insn_byte_t b2 = peek_nbyte_next(insn_byte_t, insn, 1);
6055 + if (!insn->x86_64) {
6056 + /*
6057 + * In 32-bits mode, if the [7:6] bits (mod bits of
6058 + * ModRM) on the second byte are not 11b, it is
6059 + * LDS or LES or BOUND.
6060 + */
6061 + if (X86_MODRM_MOD(b2) != 3)
6062 + goto vex_end;
6063 + }
6064 + insn->vex_prefix.bytes[0] = b;
6065 + insn->vex_prefix.bytes[1] = b2;
6066 + if (inat_is_evex_prefix(attr)) {
6067 + b2 = peek_nbyte_next(insn_byte_t, insn, 2);
6068 + insn->vex_prefix.bytes[2] = b2;
6069 + b2 = peek_nbyte_next(insn_byte_t, insn, 3);
6070 + insn->vex_prefix.bytes[3] = b2;
6071 + insn->vex_prefix.nbytes = 4;
6072 + insn->next_byte += 4;
6073 + if (insn->x86_64 && X86_VEX_W(b2))
6074 + /* VEX.W overrides opnd_size */
6075 + insn->opnd_bytes = 8;
6076 + } else if (inat_is_vex3_prefix(attr)) {
6077 + b2 = peek_nbyte_next(insn_byte_t, insn, 2);
6078 + insn->vex_prefix.bytes[2] = b2;
6079 + insn->vex_prefix.nbytes = 3;
6080 + insn->next_byte += 3;
6081 + if (insn->x86_64 && X86_VEX_W(b2))
6082 + /* VEX.W overrides opnd_size */
6083 + insn->opnd_bytes = 8;
6084 + } else {
6085 + /*
6086 + * For VEX2, fake VEX3-like byte#2.
6087 + * Makes it easier to decode vex.W, vex.vvvv,
6088 + * vex.L and vex.pp. Masking with 0x7f sets vex.W == 0.
6089 + */
6090 + insn->vex_prefix.bytes[2] = b2 & 0x7f;
6091 + insn->vex_prefix.nbytes = 2;
6092 + insn->next_byte += 2;
6093 + }
6094 + }
6095 +vex_end:
6096 + insn->vex_prefix.got = 1;
6097 +
6098 + prefixes->got = 1;
6099 +
6100 +err_out:
6101 + return;
6102 +}
6103 +
6104 +/**
6105 + * insn_get_opcode - collect opcode(s)
6106 + * @insn: &struct insn containing instruction
6107 + *
6108 + * Populates @insn->opcode, updates @insn->next_byte to point past the
6109 + * opcode byte(s), and set @insn->attr (except for groups).
6110 + * If necessary, first collects any preceding (prefix) bytes.
6111 + * Sets @insn->opcode.value = opcode1. No effect if @insn->opcode.got
6112 + * is already 1.
6113 + */
6114 +void insn_get_opcode(struct insn *insn)
6115 +{
6116 + struct insn_field *opcode = &insn->opcode;
6117 + insn_byte_t op;
6118 + int pfx_id;
6119 + if (opcode->got)
6120 + return;
6121 + if (!insn->prefixes.got)
6122 + insn_get_prefixes(insn);
6123 +
6124 + /* Get first opcode */
6125 + op = get_next(insn_byte_t, insn);
6126 + opcode->bytes[0] = op;
6127 + opcode->nbytes = 1;
6128 +
6129 + /* Check if there is VEX prefix or not */
6130 + if (insn_is_avx(insn)) {
6131 + insn_byte_t m, p;
6132 + m = insn_vex_m_bits(insn);
6133 + p = insn_vex_p_bits(insn);
6134 + insn->attr = inat_get_avx_attribute(op, m, p);
6135 + if ((inat_must_evex(insn->attr) && !insn_is_evex(insn)) ||
6136 + (!inat_accept_vex(insn->attr) &&
6137 + !inat_is_group(insn->attr)))
6138 + insn->attr = 0; /* This instruction is bad */
6139 + goto end; /* VEX has only 1 byte for opcode */
6140 + }
6141 +
6142 + insn->attr = inat_get_opcode_attribute(op);
6143 + while (inat_is_escape(insn->attr)) {
6144 + /* Get escaped opcode */
6145 + op = get_next(insn_byte_t, insn);
6146 + opcode->bytes[opcode->nbytes++] = op;
6147 + pfx_id = insn_last_prefix_id(insn);
6148 + insn->attr = inat_get_escape_attribute(op, pfx_id, insn->attr);
6149 + }
6150 + if (inat_must_vex(insn->attr))
6151 + insn->attr = 0; /* This instruction is bad */
6152 +end:
6153 + opcode->got = 1;
6154 +
6155 +err_out:
6156 + return;
6157 +}
6158 +
6159 +/**
6160 + * insn_get_modrm - collect ModRM byte, if any
6161 + * @insn: &struct insn containing instruction
6162 + *
6163 + * Populates @insn->modrm and updates @insn->next_byte to point past the
6164 + * ModRM byte, if any. If necessary, first collects the preceding bytes
6165 + * (prefixes and opcode(s)). No effect if @insn->modrm.got is already 1.
6166 + */
6167 +void insn_get_modrm(struct insn *insn)
6168 +{
6169 + struct insn_field *modrm = &insn->modrm;
6170 + insn_byte_t pfx_id, mod;
6171 + if (modrm->got)
6172 + return;
6173 + if (!insn->opcode.got)
6174 + insn_get_opcode(insn);
6175 +
6176 + if (inat_has_modrm(insn->attr)) {
6177 + mod = get_next(insn_byte_t, insn);
6178 + modrm->value = mod;
6179 + modrm->nbytes = 1;
6180 + if (inat_is_group(insn->attr)) {
6181 + pfx_id = insn_last_prefix_id(insn);
6182 + insn->attr = inat_get_group_attribute(mod, pfx_id,
6183 + insn->attr);
6184 + if (insn_is_avx(insn) && !inat_accept_vex(insn->attr))
6185 + insn->attr = 0; /* This is bad */
6186 + }
6187 + }
6188 +
6189 + if (insn->x86_64 && inat_is_force64(insn->attr))
6190 + insn->opnd_bytes = 8;
6191 + modrm->got = 1;
6192 +
6193 +err_out:
6194 + return;
6195 +}
6196 +
6197 +
6198 +/**
6199 + * insn_rip_relative() - Does instruction use RIP-relative addressing mode?
6200 + * @insn: &struct insn containing instruction
6201 + *
6202 + * If necessary, first collects the instruction up to and including the
6203 + * ModRM byte. No effect if @insn->x86_64 is 0.
6204 + */
6205 +int insn_rip_relative(struct insn *insn)
6206 +{
6207 + struct insn_field *modrm = &insn->modrm;
6208 +
6209 + if (!insn->x86_64)
6210 + return 0;
6211 + if (!modrm->got)
6212 + insn_get_modrm(insn);
6213 + /*
6214 + * For rip-relative instructions, the mod field (top 2 bits)
6215 + * is zero and the r/m field (bottom 3 bits) is 0x5.
6216 + */
6217 + return (modrm->nbytes && (modrm->value & 0xc7) == 0x5);
6218 +}
6219 +
6220 +/**
6221 + * insn_get_sib() - Get the SIB byte of instruction
6222 + * @insn: &struct insn containing instruction
6223 + *
6224 + * If necessary, first collects the instruction up to and including the
6225 + * ModRM byte.
6226 + */
6227 +void insn_get_sib(struct insn *insn)
6228 +{
6229 + insn_byte_t modrm;
6230 +
6231 + if (insn->sib.got)
6232 + return;
6233 + if (!insn->modrm.got)
6234 + insn_get_modrm(insn);
6235 + if (insn->modrm.nbytes) {
6236 + modrm = (insn_byte_t)insn->modrm.value;
6237 + if (insn->addr_bytes != 2 &&
6238 + X86_MODRM_MOD(modrm) != 3 && X86_MODRM_RM(modrm) == 4) {
6239 + insn->sib.value = get_next(insn_byte_t, insn);
6240 + insn->sib.nbytes = 1;
6241 + }
6242 + }
6243 + insn->sib.got = 1;
6244 +
6245 +err_out:
6246 + return;
6247 +}
6248 +
6249 +
6250 +/**
6251 + * insn_get_displacement() - Get the displacement of instruction
6252 + * @insn: &struct insn containing instruction
6253 + *
6254 + * If necessary, first collects the instruction up to and including the
6255 + * SIB byte.
6256 + * Displacement value is sign-expanded.
6257 + */
6258 +void insn_get_displacement(struct insn *insn)
6259 +{
6260 + insn_byte_t mod, rm, base;
6261 +
6262 + if (insn->displacement.got)
6263 + return;
6264 + if (!insn->sib.got)
6265 + insn_get_sib(insn);
6266 + if (insn->modrm.nbytes) {
6267 + /*
6268 + * Interpreting the modrm byte:
6269 + * mod = 00 - no displacement fields (exceptions below)
6270 + * mod = 01 - 1-byte displacement field
6271 + * mod = 10 - displacement field is 4 bytes, or 2 bytes if
6272 + * address size = 2 (0x67 prefix in 32-bit mode)
6273 + * mod = 11 - no memory operand
6274 + *
6275 + * If address size = 2...
6276 + * mod = 00, r/m = 110 - displacement field is 2 bytes
6277 + *
6278 + * If address size != 2...
6279 + * mod != 11, r/m = 100 - SIB byte exists
6280 + * mod = 00, SIB base = 101 - displacement field is 4 bytes
6281 + * mod = 00, r/m = 101 - rip-relative addressing, displacement
6282 + * field is 4 bytes
6283 + */
6284 + mod = X86_MODRM_MOD(insn->modrm.value);
6285 + rm = X86_MODRM_RM(insn->modrm.value);
6286 + base = X86_SIB_BASE(insn->sib.value);
6287 + if (mod == 3)
6288 + goto out;
6289 + if (mod == 1) {
6290 + insn->displacement.value = get_next(signed char, insn);
6291 + insn->displacement.nbytes = 1;
6292 + } else if (insn->addr_bytes == 2) {
6293 + if ((mod == 0 && rm == 6) || mod == 2) {
6294 + insn->displacement.value =
6295 + get_next(short, insn);
6296 + insn->displacement.nbytes = 2;
6297 + }
6298 + } else {
6299 + if ((mod == 0 && rm == 5) || mod == 2 ||
6300 + (mod == 0 && base == 5)) {
6301 + insn->displacement.value = get_next(int, insn);
6302 + insn->displacement.nbytes = 4;
6303 + }
6304 + }
6305 + }
6306 +out:
6307 + insn->displacement.got = 1;
6308 +
6309 +err_out:
6310 + return;
6311 +}
6312 +
6313 +/* Decode moffset16/32/64. Return 0 if failed */
6314 +static int __get_moffset(struct insn *insn)
6315 +{
6316 + switch (insn->addr_bytes) {
6317 + case 2:
6318 + insn->moffset1.value = get_next(short, insn);
6319 + insn->moffset1.nbytes = 2;
6320 + break;
6321 + case 4:
6322 + insn->moffset1.value = get_next(int, insn);
6323 + insn->moffset1.nbytes = 4;
6324 + break;
6325 + case 8:
6326 + insn->moffset1.value = get_next(int, insn);
6327 + insn->moffset1.nbytes = 4;
6328 + insn->moffset2.value = get_next(int, insn);
6329 + insn->moffset2.nbytes = 4;
6330 + break;
6331 + default: /* opnd_bytes must be modified manually */
6332 + goto err_out;
6333 + }
6334 + insn->moffset1.got = insn->moffset2.got = 1;
6335 +
6336 + return 1;
6337 +
6338 +err_out:
6339 + return 0;
6340 +}
6341 +
6342 +/* Decode imm v32(Iz). Return 0 if failed */
6343 +static int __get_immv32(struct insn *insn)
6344 +{
6345 + switch (insn->opnd_bytes) {
6346 + case 2:
6347 + insn->immediate.value = get_next(short, insn);
6348 + insn->immediate.nbytes = 2;
6349 + break;
6350 + case 4:
6351 + case 8:
6352 + insn->immediate.value = get_next(int, insn);
6353 + insn->immediate.nbytes = 4;
6354 + break;
6355 + default: /* opnd_bytes must be modified manually */
6356 + goto err_out;
6357 + }
6358 +
6359 + return 1;
6360 +
6361 +err_out:
6362 + return 0;
6363 +}
6364 +
6365 +/* Decode imm v64(Iv/Ov), Return 0 if failed */
6366 +static int __get_immv(struct insn *insn)
6367 +{
6368 + switch (insn->opnd_bytes) {
6369 + case 2:
6370 + insn->immediate1.value = get_next(short, insn);
6371 + insn->immediate1.nbytes = 2;
6372 + break;
6373 + case 4:
6374 + insn->immediate1.value = get_next(int, insn);
6375 + insn->immediate1.nbytes = 4;
6376 + break;
6377 + case 8:
6378 + insn->immediate1.value = get_next(int, insn);
6379 + insn->immediate1.nbytes = 4;
6380 + insn->immediate2.value = get_next(int, insn);
6381 + insn->immediate2.nbytes = 4;
6382 + break;
6383 + default: /* opnd_bytes must be modified manually */
6384 + goto err_out;
6385 + }
6386 + insn->immediate1.got = insn->immediate2.got = 1;
6387 +
6388 + return 1;
6389 +err_out:
6390 + return 0;
6391 +}
6392 +
6393 +/* Decode ptr16:16/32(Ap) */
6394 +static int __get_immptr(struct insn *insn)
6395 +{
6396 + switch (insn->opnd_bytes) {
6397 + case 2:
6398 + insn->immediate1.value = get_next(short, insn);
6399 + insn->immediate1.nbytes = 2;
6400 + break;
6401 + case 4:
6402 + insn->immediate1.value = get_next(int, insn);
6403 + insn->immediate1.nbytes = 4;
6404 + break;
6405 + case 8:
6406 + /* ptr16:64 is not exist (no segment) */
6407 + return 0;
6408 + default: /* opnd_bytes must be modified manually */
6409 + goto err_out;
6410 + }
6411 + insn->immediate2.value = get_next(unsigned short, insn);
6412 + insn->immediate2.nbytes = 2;
6413 + insn->immediate1.got = insn->immediate2.got = 1;
6414 +
6415 + return 1;
6416 +err_out:
6417 + return 0;
6418 +}
6419 +
6420 +/**
6421 + * insn_get_immediate() - Get the immediates of instruction
6422 + * @insn: &struct insn containing instruction
6423 + *
6424 + * If necessary, first collects the instruction up to and including the
6425 + * displacement bytes.
6426 + * Basically, most of immediates are sign-expanded. Unsigned-value can be
6427 + * get by bit masking with ((1 << (nbytes * 8)) - 1)
6428 + */
6429 +void insn_get_immediate(struct insn *insn)
6430 +{
6431 + if (insn->immediate.got)
6432 + return;
6433 + if (!insn->displacement.got)
6434 + insn_get_displacement(insn);
6435 +
6436 + if (inat_has_moffset(insn->attr)) {
6437 + if (!__get_moffset(insn))
6438 + goto err_out;
6439 + goto done;
6440 + }
6441 +
6442 + if (!inat_has_immediate(insn->attr))
6443 + /* no immediates */
6444 + goto done;
6445 +
6446 + switch (inat_immediate_size(insn->attr)) {
6447 + case INAT_IMM_BYTE:
6448 + insn->immediate.value = get_next(signed char, insn);
6449 + insn->immediate.nbytes = 1;
6450 + break;
6451 + case INAT_IMM_WORD:
6452 + insn->immediate.value = get_next(short, insn);
6453 + insn->immediate.nbytes = 2;
6454 + break;
6455 + case INAT_IMM_DWORD:
6456 + insn->immediate.value = get_next(int, insn);
6457 + insn->immediate.nbytes = 4;
6458 + break;
6459 + case INAT_IMM_QWORD:
6460 + insn->immediate1.value = get_next(int, insn);
6461 + insn->immediate1.nbytes = 4;
6462 + insn->immediate2.value = get_next(int, insn);
6463 + insn->immediate2.nbytes = 4;
6464 + break;
6465 + case INAT_IMM_PTR:
6466 + if (!__get_immptr(insn))
6467 + goto err_out;
6468 + break;
6469 + case INAT_IMM_VWORD32:
6470 + if (!__get_immv32(insn))
6471 + goto err_out;
6472 + break;
6473 + case INAT_IMM_VWORD:
6474 + if (!__get_immv(insn))
6475 + goto err_out;
6476 + break;
6477 + default:
6478 + /* Here, insn must have an immediate, but failed */
6479 + goto err_out;
6480 + }
6481 + if (inat_has_second_immediate(insn->attr)) {
6482 + insn->immediate2.value = get_next(signed char, insn);
6483 + insn->immediate2.nbytes = 1;
6484 + }
6485 +done:
6486 + insn->immediate.got = 1;
6487 +
6488 +err_out:
6489 + return;
6490 +}
6491 +
6492 +/**
6493 + * insn_get_length() - Get the length of instruction
6494 + * @insn: &struct insn containing instruction
6495 + *
6496 + * If necessary, first collects the instruction up to and including the
6497 + * immediates bytes.
6498 + */
6499 +void insn_get_length(struct insn *insn)
6500 +{
6501 + if (insn->length)
6502 + return;
6503 + if (!insn->immediate.got)
6504 + insn_get_immediate(insn);
6505 + insn->length = (unsigned char)((unsigned long)insn->next_byte
6506 + - (unsigned long)insn->kaddr);
6507 +}
6508 diff --git a/tools/objtool/arch/x86/lib/x86-opcode-map.txt b/tools/objtool/arch/x86/lib/x86-opcode-map.txt
6509 new file mode 100644
6510 index 000000000000..1754e094bc28
6511 --- /dev/null
6512 +++ b/tools/objtool/arch/x86/lib/x86-opcode-map.txt
6513 @@ -0,0 +1,1063 @@
6514 +# x86 Opcode Maps
6515 +#
6516 +# This is (mostly) based on following documentations.
6517 +# - Intel(R) 64 and IA-32 Architectures Software Developer's Manual Vol.2C
6518 +# (#326018-047US, June 2013)
6519 +#
6520 +#<Opcode maps>
6521 +# Table: table-name
6522 +# Referrer: escaped-name
6523 +# AVXcode: avx-code
6524 +# opcode: mnemonic|GrpXXX [operand1[,operand2...]] [(extra1)[,(extra2)...] [| 2nd-mnemonic ...]
6525 +# (or)
6526 +# opcode: escape # escaped-name
6527 +# EndTable
6528 +#
6529 +# mnemonics that begin with lowercase 'v' accept a VEX or EVEX prefix
6530 +# mnemonics that begin with lowercase 'k' accept a VEX prefix
6531 +#
6532 +#<group maps>
6533 +# GrpTable: GrpXXX
6534 +# reg: mnemonic [operand1[,operand2...]] [(extra1)[,(extra2)...] [| 2nd-mnemonic ...]
6535 +# EndTable
6536 +#
6537 +# AVX Superscripts
6538 +# (ev): this opcode requires EVEX prefix.
6539 +# (evo): this opcode is changed by EVEX prefix (EVEX opcode)
6540 +# (v): this opcode requires VEX prefix.
6541 +# (v1): this opcode only supports 128bit VEX.
6542 +#
6543 +# Last Prefix Superscripts
6544 +# - (66): the last prefix is 0x66
6545 +# - (F3): the last prefix is 0xF3
6546 +# - (F2): the last prefix is 0xF2
6547 +# - (!F3) : the last prefix is not 0xF3 (including non-last prefix case)
6548 +# - (66&F2): Both 0x66 and 0xF2 prefixes are specified.
6549 +
6550 +Table: one byte opcode
6551 +Referrer:
6552 +AVXcode:
6553 +# 0x00 - 0x0f
6554 +00: ADD Eb,Gb
6555 +01: ADD Ev,Gv
6556 +02: ADD Gb,Eb
6557 +03: ADD Gv,Ev
6558 +04: ADD AL,Ib
6559 +05: ADD rAX,Iz
6560 +06: PUSH ES (i64)
6561 +07: POP ES (i64)
6562 +08: OR Eb,Gb
6563 +09: OR Ev,Gv
6564 +0a: OR Gb,Eb
6565 +0b: OR Gv,Ev
6566 +0c: OR AL,Ib
6567 +0d: OR rAX,Iz
6568 +0e: PUSH CS (i64)
6569 +0f: escape # 2-byte escape
6570 +# 0x10 - 0x1f
6571 +10: ADC Eb,Gb
6572 +11: ADC Ev,Gv
6573 +12: ADC Gb,Eb
6574 +13: ADC Gv,Ev
6575 +14: ADC AL,Ib
6576 +15: ADC rAX,Iz
6577 +16: PUSH SS (i64)
6578 +17: POP SS (i64)
6579 +18: SBB Eb,Gb
6580 +19: SBB Ev,Gv
6581 +1a: SBB Gb,Eb
6582 +1b: SBB Gv,Ev
6583 +1c: SBB AL,Ib
6584 +1d: SBB rAX,Iz
6585 +1e: PUSH DS (i64)
6586 +1f: POP DS (i64)
6587 +# 0x20 - 0x2f
6588 +20: AND Eb,Gb
6589 +21: AND Ev,Gv
6590 +22: AND Gb,Eb
6591 +23: AND Gv,Ev
6592 +24: AND AL,Ib
6593 +25: AND rAx,Iz
6594 +26: SEG=ES (Prefix)
6595 +27: DAA (i64)
6596 +28: SUB Eb,Gb
6597 +29: SUB Ev,Gv
6598 +2a: SUB Gb,Eb
6599 +2b: SUB Gv,Ev
6600 +2c: SUB AL,Ib
6601 +2d: SUB rAX,Iz
6602 +2e: SEG=CS (Prefix)
6603 +2f: DAS (i64)
6604 +# 0x30 - 0x3f
6605 +30: XOR Eb,Gb
6606 +31: XOR Ev,Gv
6607 +32: XOR Gb,Eb
6608 +33: XOR Gv,Ev
6609 +34: XOR AL,Ib
6610 +35: XOR rAX,Iz
6611 +36: SEG=SS (Prefix)
6612 +37: AAA (i64)
6613 +38: CMP Eb,Gb
6614 +39: CMP Ev,Gv
6615 +3a: CMP Gb,Eb
6616 +3b: CMP Gv,Ev
6617 +3c: CMP AL,Ib
6618 +3d: CMP rAX,Iz
6619 +3e: SEG=DS (Prefix)
6620 +3f: AAS (i64)
6621 +# 0x40 - 0x4f
6622 +40: INC eAX (i64) | REX (o64)
6623 +41: INC eCX (i64) | REX.B (o64)
6624 +42: INC eDX (i64) | REX.X (o64)
6625 +43: INC eBX (i64) | REX.XB (o64)
6626 +44: INC eSP (i64) | REX.R (o64)
6627 +45: INC eBP (i64) | REX.RB (o64)
6628 +46: INC eSI (i64) | REX.RX (o64)
6629 +47: INC eDI (i64) | REX.RXB (o64)
6630 +48: DEC eAX (i64) | REX.W (o64)
6631 +49: DEC eCX (i64) | REX.WB (o64)
6632 +4a: DEC eDX (i64) | REX.WX (o64)
6633 +4b: DEC eBX (i64) | REX.WXB (o64)
6634 +4c: DEC eSP (i64) | REX.WR (o64)
6635 +4d: DEC eBP (i64) | REX.WRB (o64)
6636 +4e: DEC eSI (i64) | REX.WRX (o64)
6637 +4f: DEC eDI (i64) | REX.WRXB (o64)
6638 +# 0x50 - 0x5f
6639 +50: PUSH rAX/r8 (d64)
6640 +51: PUSH rCX/r9 (d64)
6641 +52: PUSH rDX/r10 (d64)
6642 +53: PUSH rBX/r11 (d64)
6643 +54: PUSH rSP/r12 (d64)
6644 +55: PUSH rBP/r13 (d64)
6645 +56: PUSH rSI/r14 (d64)
6646 +57: PUSH rDI/r15 (d64)
6647 +58: POP rAX/r8 (d64)
6648 +59: POP rCX/r9 (d64)
6649 +5a: POP rDX/r10 (d64)
6650 +5b: POP rBX/r11 (d64)
6651 +5c: POP rSP/r12 (d64)
6652 +5d: POP rBP/r13 (d64)
6653 +5e: POP rSI/r14 (d64)
6654 +5f: POP rDI/r15 (d64)
6655 +# 0x60 - 0x6f
6656 +60: PUSHA/PUSHAD (i64)
6657 +61: POPA/POPAD (i64)
6658 +62: BOUND Gv,Ma (i64) | EVEX (Prefix)
6659 +63: ARPL Ew,Gw (i64) | MOVSXD Gv,Ev (o64)
6660 +64: SEG=FS (Prefix)
6661 +65: SEG=GS (Prefix)
6662 +66: Operand-Size (Prefix)
6663 +67: Address-Size (Prefix)
6664 +68: PUSH Iz (d64)
6665 +69: IMUL Gv,Ev,Iz
6666 +6a: PUSH Ib (d64)
6667 +6b: IMUL Gv,Ev,Ib
6668 +6c: INS/INSB Yb,DX
6669 +6d: INS/INSW/INSD Yz,DX
6670 +6e: OUTS/OUTSB DX,Xb
6671 +6f: OUTS/OUTSW/OUTSD DX,Xz
6672 +# 0x70 - 0x7f
6673 +70: JO Jb
6674 +71: JNO Jb
6675 +72: JB/JNAE/JC Jb
6676 +73: JNB/JAE/JNC Jb
6677 +74: JZ/JE Jb
6678 +75: JNZ/JNE Jb
6679 +76: JBE/JNA Jb
6680 +77: JNBE/JA Jb
6681 +78: JS Jb
6682 +79: JNS Jb
6683 +7a: JP/JPE Jb
6684 +7b: JNP/JPO Jb
6685 +7c: JL/JNGE Jb
6686 +7d: JNL/JGE Jb
6687 +7e: JLE/JNG Jb
6688 +7f: JNLE/JG Jb
6689 +# 0x80 - 0x8f
6690 +80: Grp1 Eb,Ib (1A)
6691 +81: Grp1 Ev,Iz (1A)
6692 +82: Grp1 Eb,Ib (1A),(i64)
6693 +83: Grp1 Ev,Ib (1A)
6694 +84: TEST Eb,Gb
6695 +85: TEST Ev,Gv
6696 +86: XCHG Eb,Gb
6697 +87: XCHG Ev,Gv
6698 +88: MOV Eb,Gb
6699 +89: MOV Ev,Gv
6700 +8a: MOV Gb,Eb
6701 +8b: MOV Gv,Ev
6702 +8c: MOV Ev,Sw
6703 +8d: LEA Gv,M
6704 +8e: MOV Sw,Ew
6705 +8f: Grp1A (1A) | POP Ev (d64)
6706 +# 0x90 - 0x9f
6707 +90: NOP | PAUSE (F3) | XCHG r8,rAX
6708 +91: XCHG rCX/r9,rAX
6709 +92: XCHG rDX/r10,rAX
6710 +93: XCHG rBX/r11,rAX
6711 +94: XCHG rSP/r12,rAX
6712 +95: XCHG rBP/r13,rAX
6713 +96: XCHG rSI/r14,rAX
6714 +97: XCHG rDI/r15,rAX
6715 +98: CBW/CWDE/CDQE
6716 +99: CWD/CDQ/CQO
6717 +9a: CALLF Ap (i64)
6718 +9b: FWAIT/WAIT
6719 +9c: PUSHF/D/Q Fv (d64)
6720 +9d: POPF/D/Q Fv (d64)
6721 +9e: SAHF
6722 +9f: LAHF
6723 +# 0xa0 - 0xaf
6724 +a0: MOV AL,Ob
6725 +a1: MOV rAX,Ov
6726 +a2: MOV Ob,AL
6727 +a3: MOV Ov,rAX
6728 +a4: MOVS/B Yb,Xb
6729 +a5: MOVS/W/D/Q Yv,Xv
6730 +a6: CMPS/B Xb,Yb
6731 +a7: CMPS/W/D Xv,Yv
6732 +a8: TEST AL,Ib
6733 +a9: TEST rAX,Iz
6734 +aa: STOS/B Yb,AL
6735 +ab: STOS/W/D/Q Yv,rAX
6736 +ac: LODS/B AL,Xb
6737 +ad: LODS/W/D/Q rAX,Xv
6738 +ae: SCAS/B AL,Yb
6739 +# Note: The May 2011 Intel manual shows Xv for the second parameter of the
6740 +# next instruction but Yv is correct
6741 +af: SCAS/W/D/Q rAX,Yv
6742 +# 0xb0 - 0xbf
6743 +b0: MOV AL/R8L,Ib
6744 +b1: MOV CL/R9L,Ib
6745 +b2: MOV DL/R10L,Ib
6746 +b3: MOV BL/R11L,Ib
6747 +b4: MOV AH/R12L,Ib
6748 +b5: MOV CH/R13L,Ib
6749 +b6: MOV DH/R14L,Ib
6750 +b7: MOV BH/R15L,Ib
6751 +b8: MOV rAX/r8,Iv
6752 +b9: MOV rCX/r9,Iv
6753 +ba: MOV rDX/r10,Iv
6754 +bb: MOV rBX/r11,Iv
6755 +bc: MOV rSP/r12,Iv
6756 +bd: MOV rBP/r13,Iv
6757 +be: MOV rSI/r14,Iv
6758 +bf: MOV rDI/r15,Iv
6759 +# 0xc0 - 0xcf
6760 +c0: Grp2 Eb,Ib (1A)
6761 +c1: Grp2 Ev,Ib (1A)
6762 +c2: RETN Iw (f64)
6763 +c3: RETN
6764 +c4: LES Gz,Mp (i64) | VEX+2byte (Prefix)
6765 +c5: LDS Gz,Mp (i64) | VEX+1byte (Prefix)
6766 +c6: Grp11A Eb,Ib (1A)
6767 +c7: Grp11B Ev,Iz (1A)
6768 +c8: ENTER Iw,Ib
6769 +c9: LEAVE (d64)
6770 +ca: RETF Iw
6771 +cb: RETF
6772 +cc: INT3
6773 +cd: INT Ib
6774 +ce: INTO (i64)
6775 +cf: IRET/D/Q
6776 +# 0xd0 - 0xdf
6777 +d0: Grp2 Eb,1 (1A)
6778 +d1: Grp2 Ev,1 (1A)
6779 +d2: Grp2 Eb,CL (1A)
6780 +d3: Grp2 Ev,CL (1A)
6781 +d4: AAM Ib (i64)
6782 +d5: AAD Ib (i64)
6783 +d6:
6784 +d7: XLAT/XLATB
6785 +d8: ESC
6786 +d9: ESC
6787 +da: ESC
6788 +db: ESC
6789 +dc: ESC
6790 +dd: ESC
6791 +de: ESC
6792 +df: ESC
6793 +# 0xe0 - 0xef
6794 +# Note: "forced64" is Intel CPU behavior: they ignore 0x66 prefix
6795 +# in 64-bit mode. AMD CPUs accept 0x66 prefix, it causes RIP truncation
6796 +# to 16 bits. In 32-bit mode, 0x66 is accepted by both Intel and AMD.
6797 +e0: LOOPNE/LOOPNZ Jb (f64)
6798 +e1: LOOPE/LOOPZ Jb (f64)
6799 +e2: LOOP Jb (f64)
6800 +e3: JrCXZ Jb (f64)
6801 +e4: IN AL,Ib
6802 +e5: IN eAX,Ib
6803 +e6: OUT Ib,AL
6804 +e7: OUT Ib,eAX
6805 +# With 0x66 prefix in 64-bit mode, for AMD CPUs immediate offset
6806 +# in "near" jumps and calls is 16-bit. For CALL,
6807 +# push of return address is 16-bit wide, RSP is decremented by 2
6808 +# but is not truncated to 16 bits, unlike RIP.
6809 +e8: CALL Jz (f64)
6810 +e9: JMP-near Jz (f64)
6811 +ea: JMP-far Ap (i64)
6812 +eb: JMP-short Jb (f64)
6813 +ec: IN AL,DX
6814 +ed: IN eAX,DX
6815 +ee: OUT DX,AL
6816 +ef: OUT DX,eAX
6817 +# 0xf0 - 0xff
6818 +f0: LOCK (Prefix)
6819 +f1:
6820 +f2: REPNE (Prefix) | XACQUIRE (Prefix)
6821 +f3: REP/REPE (Prefix) | XRELEASE (Prefix)
6822 +f4: HLT
6823 +f5: CMC
6824 +f6: Grp3_1 Eb (1A)
6825 +f7: Grp3_2 Ev (1A)
6826 +f8: CLC
6827 +f9: STC
6828 +fa: CLI
6829 +fb: STI
6830 +fc: CLD
6831 +fd: STD
6832 +fe: Grp4 (1A)
6833 +ff: Grp5 (1A)
6834 +EndTable
6835 +
6836 +Table: 2-byte opcode (0x0f)
6837 +Referrer: 2-byte escape
6838 +AVXcode: 1
6839 +# 0x0f 0x00-0x0f
6840 +00: Grp6 (1A)
6841 +01: Grp7 (1A)
6842 +02: LAR Gv,Ew
6843 +03: LSL Gv,Ew
6844 +04:
6845 +05: SYSCALL (o64)
6846 +06: CLTS
6847 +07: SYSRET (o64)
6848 +08: INVD
6849 +09: WBINVD
6850 +0a:
6851 +0b: UD2 (1B)
6852 +0c:
6853 +# AMD's prefetch group. Intel supports prefetchw(/1) only.
6854 +0d: GrpP
6855 +0e: FEMMS
6856 +# 3DNow! uses the last imm byte as opcode extension.
6857 +0f: 3DNow! Pq,Qq,Ib
6858 +# 0x0f 0x10-0x1f
6859 +# NOTE: According to Intel SDM opcode map, vmovups and vmovupd has no operands
6860 +# but it actually has operands. And also, vmovss and vmovsd only accept 128bit.
6861 +# MOVSS/MOVSD has too many forms(3) on SDM. This map just shows a typical form.
6862 +# Many AVX instructions lack v1 superscript, according to Intel AVX-Prgramming
6863 +# Reference A.1
6864 +10: vmovups Vps,Wps | vmovupd Vpd,Wpd (66) | vmovss Vx,Hx,Wss (F3),(v1) | vmovsd Vx,Hx,Wsd (F2),(v1)
6865 +11: vmovups Wps,Vps | vmovupd Wpd,Vpd (66) | vmovss Wss,Hx,Vss (F3),(v1) | vmovsd Wsd,Hx,Vsd (F2),(v1)
6866 +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)
6867 +13: vmovlps Mq,Vq (v1) | vmovlpd Mq,Vq (66),(v1)
6868 +14: vunpcklps Vx,Hx,Wx | vunpcklpd Vx,Hx,Wx (66)
6869 +15: vunpckhps Vx,Hx,Wx | vunpckhpd Vx,Hx,Wx (66)
6870 +16: vmovhps Vdq,Hq,Mq (v1) | vmovlhps Vdq,Hq,Uq (v1) | vmovhpd Vdq,Hq,Mq (66),(v1) | vmovshdup Vx,Wx (F3)
6871 +17: vmovhps Mq,Vq (v1) | vmovhpd Mq,Vq (66),(v1)
6872 +18: Grp16 (1A)
6873 +19:
6874 +# Intel SDM opcode map does not list MPX instructions. For now using Gv for
6875 +# bnd registers and Ev for everything else is OK because the instruction
6876 +# decoder does not use the information except as an indication that there is
6877 +# a ModR/M byte.
6878 +1a: BNDCL Gv,Ev (F3) | BNDCU Gv,Ev (F2) | BNDMOV Gv,Ev (66) | BNDLDX Gv,Ev
6879 +1b: BNDCN Gv,Ev (F2) | BNDMOV Ev,Gv (66) | BNDMK Gv,Ev (F3) | BNDSTX Ev,Gv
6880 +1c:
6881 +1d:
6882 +1e:
6883 +1f: NOP Ev
6884 +# 0x0f 0x20-0x2f
6885 +20: MOV Rd,Cd
6886 +21: MOV Rd,Dd
6887 +22: MOV Cd,Rd
6888 +23: MOV Dd,Rd
6889 +24:
6890 +25:
6891 +26:
6892 +27:
6893 +28: vmovaps Vps,Wps | vmovapd Vpd,Wpd (66)
6894 +29: vmovaps Wps,Vps | vmovapd Wpd,Vpd (66)
6895 +2a: cvtpi2ps Vps,Qpi | cvtpi2pd Vpd,Qpi (66) | vcvtsi2ss Vss,Hss,Ey (F3),(v1) | vcvtsi2sd Vsd,Hsd,Ey (F2),(v1)
6896 +2b: vmovntps Mps,Vps | vmovntpd Mpd,Vpd (66)
6897 +2c: cvttps2pi Ppi,Wps | cvttpd2pi Ppi,Wpd (66) | vcvttss2si Gy,Wss (F3),(v1) | vcvttsd2si Gy,Wsd (F2),(v1)
6898 +2d: cvtps2pi Ppi,Wps | cvtpd2pi Qpi,Wpd (66) | vcvtss2si Gy,Wss (F3),(v1) | vcvtsd2si Gy,Wsd (F2),(v1)
6899 +2e: vucomiss Vss,Wss (v1) | vucomisd Vsd,Wsd (66),(v1)
6900 +2f: vcomiss Vss,Wss (v1) | vcomisd Vsd,Wsd (66),(v1)
6901 +# 0x0f 0x30-0x3f
6902 +30: WRMSR
6903 +31: RDTSC
6904 +32: RDMSR
6905 +33: RDPMC
6906 +34: SYSENTER
6907 +35: SYSEXIT
6908 +36:
6909 +37: GETSEC
6910 +38: escape # 3-byte escape 1
6911 +39:
6912 +3a: escape # 3-byte escape 2
6913 +3b:
6914 +3c:
6915 +3d:
6916 +3e:
6917 +3f:
6918 +# 0x0f 0x40-0x4f
6919 +40: CMOVO Gv,Ev
6920 +41: CMOVNO Gv,Ev | kandw/q Vk,Hk,Uk | kandb/d Vk,Hk,Uk (66)
6921 +42: CMOVB/C/NAE Gv,Ev | kandnw/q Vk,Hk,Uk | kandnb/d Vk,Hk,Uk (66)
6922 +43: CMOVAE/NB/NC Gv,Ev
6923 +44: CMOVE/Z Gv,Ev | knotw/q Vk,Uk | knotb/d Vk,Uk (66)
6924 +45: CMOVNE/NZ Gv,Ev | korw/q Vk,Hk,Uk | korb/d Vk,Hk,Uk (66)
6925 +46: CMOVBE/NA Gv,Ev | kxnorw/q Vk,Hk,Uk | kxnorb/d Vk,Hk,Uk (66)
6926 +47: CMOVA/NBE Gv,Ev | kxorw/q Vk,Hk,Uk | kxorb/d Vk,Hk,Uk (66)
6927 +48: CMOVS Gv,Ev
6928 +49: CMOVNS Gv,Ev
6929 +4a: CMOVP/PE Gv,Ev | kaddw/q Vk,Hk,Uk | kaddb/d Vk,Hk,Uk (66)
6930 +4b: CMOVNP/PO Gv,Ev | kunpckbw Vk,Hk,Uk (66) | kunpckwd/dq Vk,Hk,Uk
6931 +4c: CMOVL/NGE Gv,Ev
6932 +4d: CMOVNL/GE Gv,Ev
6933 +4e: CMOVLE/NG Gv,Ev
6934 +4f: CMOVNLE/G Gv,Ev
6935 +# 0x0f 0x50-0x5f
6936 +50: vmovmskps Gy,Ups | vmovmskpd Gy,Upd (66)
6937 +51: vsqrtps Vps,Wps | vsqrtpd Vpd,Wpd (66) | vsqrtss Vss,Hss,Wss (F3),(v1) | vsqrtsd Vsd,Hsd,Wsd (F2),(v1)
6938 +52: vrsqrtps Vps,Wps | vrsqrtss Vss,Hss,Wss (F3),(v1)
6939 +53: vrcpps Vps,Wps | vrcpss Vss,Hss,Wss (F3),(v1)
6940 +54: vandps Vps,Hps,Wps | vandpd Vpd,Hpd,Wpd (66)
6941 +55: vandnps Vps,Hps,Wps | vandnpd Vpd,Hpd,Wpd (66)
6942 +56: vorps Vps,Hps,Wps | vorpd Vpd,Hpd,Wpd (66)
6943 +57: vxorps Vps,Hps,Wps | vxorpd Vpd,Hpd,Wpd (66)
6944 +58: vaddps Vps,Hps,Wps | vaddpd Vpd,Hpd,Wpd (66) | vaddss Vss,Hss,Wss (F3),(v1) | vaddsd Vsd,Hsd,Wsd (F2),(v1)
6945 +59: vmulps Vps,Hps,Wps | vmulpd Vpd,Hpd,Wpd (66) | vmulss Vss,Hss,Wss (F3),(v1) | vmulsd Vsd,Hsd,Wsd (F2),(v1)
6946 +5a: vcvtps2pd Vpd,Wps | vcvtpd2ps Vps,Wpd (66) | vcvtss2sd Vsd,Hx,Wss (F3),(v1) | vcvtsd2ss Vss,Hx,Wsd (F2),(v1)
6947 +5b: vcvtdq2ps Vps,Wdq | vcvtqq2ps Vps,Wqq (evo) | vcvtps2dq Vdq,Wps (66) | vcvttps2dq Vdq,Wps (F3)
6948 +5c: vsubps Vps,Hps,Wps | vsubpd Vpd,Hpd,Wpd (66) | vsubss Vss,Hss,Wss (F3),(v1) | vsubsd Vsd,Hsd,Wsd (F2),(v1)
6949 +5d: vminps Vps,Hps,Wps | vminpd Vpd,Hpd,Wpd (66) | vminss Vss,Hss,Wss (F3),(v1) | vminsd Vsd,Hsd,Wsd (F2),(v1)
6950 +5e: vdivps Vps,Hps,Wps | vdivpd Vpd,Hpd,Wpd (66) | vdivss Vss,Hss,Wss (F3),(v1) | vdivsd Vsd,Hsd,Wsd (F2),(v1)
6951 +5f: vmaxps Vps,Hps,Wps | vmaxpd Vpd,Hpd,Wpd (66) | vmaxss Vss,Hss,Wss (F3),(v1) | vmaxsd Vsd,Hsd,Wsd (F2),(v1)
6952 +# 0x0f 0x60-0x6f
6953 +60: punpcklbw Pq,Qd | vpunpcklbw Vx,Hx,Wx (66),(v1)
6954 +61: punpcklwd Pq,Qd | vpunpcklwd Vx,Hx,Wx (66),(v1)
6955 +62: punpckldq Pq,Qd | vpunpckldq Vx,Hx,Wx (66),(v1)
6956 +63: packsswb Pq,Qq | vpacksswb Vx,Hx,Wx (66),(v1)
6957 +64: pcmpgtb Pq,Qq | vpcmpgtb Vx,Hx,Wx (66),(v1)
6958 +65: pcmpgtw Pq,Qq | vpcmpgtw Vx,Hx,Wx (66),(v1)
6959 +66: pcmpgtd Pq,Qq | vpcmpgtd Vx,Hx,Wx (66),(v1)
6960 +67: packuswb Pq,Qq | vpackuswb Vx,Hx,Wx (66),(v1)
6961 +68: punpckhbw Pq,Qd | vpunpckhbw Vx,Hx,Wx (66),(v1)
6962 +69: punpckhwd Pq,Qd | vpunpckhwd Vx,Hx,Wx (66),(v1)
6963 +6a: punpckhdq Pq,Qd | vpunpckhdq Vx,Hx,Wx (66),(v1)
6964 +6b: packssdw Pq,Qd | vpackssdw Vx,Hx,Wx (66),(v1)
6965 +6c: vpunpcklqdq Vx,Hx,Wx (66),(v1)
6966 +6d: vpunpckhqdq Vx,Hx,Wx (66),(v1)
6967 +6e: movd/q Pd,Ey | vmovd/q Vy,Ey (66),(v1)
6968 +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)
6969 +# 0x0f 0x70-0x7f
6970 +70: pshufw Pq,Qq,Ib | vpshufd Vx,Wx,Ib (66),(v1) | vpshufhw Vx,Wx,Ib (F3),(v1) | vpshuflw Vx,Wx,Ib (F2),(v1)
6971 +71: Grp12 (1A)
6972 +72: Grp13 (1A)
6973 +73: Grp14 (1A)
6974 +74: pcmpeqb Pq,Qq | vpcmpeqb Vx,Hx,Wx (66),(v1)
6975 +75: pcmpeqw Pq,Qq | vpcmpeqw Vx,Hx,Wx (66),(v1)
6976 +76: pcmpeqd Pq,Qq | vpcmpeqd Vx,Hx,Wx (66),(v1)
6977 +# Note: Remove (v), because vzeroall and vzeroupper becomes emms without VEX.
6978 +77: emms | vzeroupper | vzeroall
6979 +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)
6980 +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)
6981 +7a: vcvtudq2pd/uqq2pd Vpd,Wx (F3),(ev) | vcvtudq2ps/uqq2ps Vpd,Wx (F2),(ev) | vcvttps2qq/pd2qq Vx,Wx (66),(ev)
6982 +7b: vcvtusi2sd Vpd,Hpd,Ev (F2),(ev) | vcvtusi2ss Vps,Hps,Ev (F3),(ev) | vcvtps2qq/pd2qq Vx,Wx (66),(ev)
6983 +7c: vhaddpd Vpd,Hpd,Wpd (66) | vhaddps Vps,Hps,Wps (F2)
6984 +7d: vhsubpd Vpd,Hpd,Wpd (66) | vhsubps Vps,Hps,Wps (F2)
6985 +7e: movd/q Ey,Pd | vmovd/q Ey,Vy (66),(v1) | vmovq Vq,Wq (F3),(v1)
6986 +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)
6987 +# 0x0f 0x80-0x8f
6988 +# Note: "forced64" is Intel CPU behavior (see comment about CALL insn).
6989 +80: JO Jz (f64)
6990 +81: JNO Jz (f64)
6991 +82: JB/JC/JNAE Jz (f64)
6992 +83: JAE/JNB/JNC Jz (f64)
6993 +84: JE/JZ Jz (f64)
6994 +85: JNE/JNZ Jz (f64)
6995 +86: JBE/JNA Jz (f64)
6996 +87: JA/JNBE Jz (f64)
6997 +88: JS Jz (f64)
6998 +89: JNS Jz (f64)
6999 +8a: JP/JPE Jz (f64)
7000 +8b: JNP/JPO Jz (f64)
7001 +8c: JL/JNGE Jz (f64)
7002 +8d: JNL/JGE Jz (f64)
7003 +8e: JLE/JNG Jz (f64)
7004 +8f: JNLE/JG Jz (f64)
7005 +# 0x0f 0x90-0x9f
7006 +90: SETO Eb | kmovw/q Vk,Wk | kmovb/d Vk,Wk (66)
7007 +91: SETNO Eb | kmovw/q Mv,Vk | kmovb/d Mv,Vk (66)
7008 +92: SETB/C/NAE Eb | kmovw Vk,Rv | kmovb Vk,Rv (66) | kmovq/d Vk,Rv (F2)
7009 +93: SETAE/NB/NC Eb | kmovw Gv,Uk | kmovb Gv,Uk (66) | kmovq/d Gv,Uk (F2)
7010 +94: SETE/Z Eb
7011 +95: SETNE/NZ Eb
7012 +96: SETBE/NA Eb
7013 +97: SETA/NBE Eb
7014 +98: SETS Eb | kortestw/q Vk,Uk | kortestb/d Vk,Uk (66)
7015 +99: SETNS Eb | ktestw/q Vk,Uk | ktestb/d Vk,Uk (66)
7016 +9a: SETP/PE Eb
7017 +9b: SETNP/PO Eb
7018 +9c: SETL/NGE Eb
7019 +9d: SETNL/GE Eb
7020 +9e: SETLE/NG Eb
7021 +9f: SETNLE/G Eb
7022 +# 0x0f 0xa0-0xaf
7023 +a0: PUSH FS (d64)
7024 +a1: POP FS (d64)
7025 +a2: CPUID
7026 +a3: BT Ev,Gv
7027 +a4: SHLD Ev,Gv,Ib
7028 +a5: SHLD Ev,Gv,CL
7029 +a6: GrpPDLK
7030 +a7: GrpRNG
7031 +a8: PUSH GS (d64)
7032 +a9: POP GS (d64)
7033 +aa: RSM
7034 +ab: BTS Ev,Gv
7035 +ac: SHRD Ev,Gv,Ib
7036 +ad: SHRD Ev,Gv,CL
7037 +ae: Grp15 (1A),(1C)
7038 +af: IMUL Gv,Ev
7039 +# 0x0f 0xb0-0xbf
7040 +b0: CMPXCHG Eb,Gb
7041 +b1: CMPXCHG Ev,Gv
7042 +b2: LSS Gv,Mp
7043 +b3: BTR Ev,Gv
7044 +b4: LFS Gv,Mp
7045 +b5: LGS Gv,Mp
7046 +b6: MOVZX Gv,Eb
7047 +b7: MOVZX Gv,Ew
7048 +b8: JMPE (!F3) | POPCNT Gv,Ev (F3)
7049 +b9: Grp10 (1A)
7050 +ba: Grp8 Ev,Ib (1A)
7051 +bb: BTC Ev,Gv
7052 +bc: BSF Gv,Ev (!F3) | TZCNT Gv,Ev (F3)
7053 +bd: BSR Gv,Ev (!F3) | LZCNT Gv,Ev (F3)
7054 +be: MOVSX Gv,Eb
7055 +bf: MOVSX Gv,Ew
7056 +# 0x0f 0xc0-0xcf
7057 +c0: XADD Eb,Gb
7058 +c1: XADD Ev,Gv
7059 +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)
7060 +c3: movnti My,Gy
7061 +c4: pinsrw Pq,Ry/Mw,Ib | vpinsrw Vdq,Hdq,Ry/Mw,Ib (66),(v1)
7062 +c5: pextrw Gd,Nq,Ib | vpextrw Gd,Udq,Ib (66),(v1)
7063 +c6: vshufps Vps,Hps,Wps,Ib | vshufpd Vpd,Hpd,Wpd,Ib (66)
7064 +c7: Grp9 (1A)
7065 +c8: BSWAP RAX/EAX/R8/R8D
7066 +c9: BSWAP RCX/ECX/R9/R9D
7067 +ca: BSWAP RDX/EDX/R10/R10D
7068 +cb: BSWAP RBX/EBX/R11/R11D
7069 +cc: BSWAP RSP/ESP/R12/R12D
7070 +cd: BSWAP RBP/EBP/R13/R13D
7071 +ce: BSWAP RSI/ESI/R14/R14D
7072 +cf: BSWAP RDI/EDI/R15/R15D
7073 +# 0x0f 0xd0-0xdf
7074 +d0: vaddsubpd Vpd,Hpd,Wpd (66) | vaddsubps Vps,Hps,Wps (F2)
7075 +d1: psrlw Pq,Qq | vpsrlw Vx,Hx,Wx (66),(v1)
7076 +d2: psrld Pq,Qq | vpsrld Vx,Hx,Wx (66),(v1)
7077 +d3: psrlq Pq,Qq | vpsrlq Vx,Hx,Wx (66),(v1)
7078 +d4: paddq Pq,Qq | vpaddq Vx,Hx,Wx (66),(v1)
7079 +d5: pmullw Pq,Qq | vpmullw Vx,Hx,Wx (66),(v1)
7080 +d6: vmovq Wq,Vq (66),(v1) | movq2dq Vdq,Nq (F3) | movdq2q Pq,Uq (F2)
7081 +d7: pmovmskb Gd,Nq | vpmovmskb Gd,Ux (66),(v1)
7082 +d8: psubusb Pq,Qq | vpsubusb Vx,Hx,Wx (66),(v1)
7083 +d9: psubusw Pq,Qq | vpsubusw Vx,Hx,Wx (66),(v1)
7084 +da: pminub Pq,Qq | vpminub Vx,Hx,Wx (66),(v1)
7085 +db: pand Pq,Qq | vpand Vx,Hx,Wx (66),(v1) | vpandd/q Vx,Hx,Wx (66),(evo)
7086 +dc: paddusb Pq,Qq | vpaddusb Vx,Hx,Wx (66),(v1)
7087 +dd: paddusw Pq,Qq | vpaddusw Vx,Hx,Wx (66),(v1)
7088 +de: pmaxub Pq,Qq | vpmaxub Vx,Hx,Wx (66),(v1)
7089 +df: pandn Pq,Qq | vpandn Vx,Hx,Wx (66),(v1) | vpandnd/q Vx,Hx,Wx (66),(evo)
7090 +# 0x0f 0xe0-0xef
7091 +e0: pavgb Pq,Qq | vpavgb Vx,Hx,Wx (66),(v1)
7092 +e1: psraw Pq,Qq | vpsraw Vx,Hx,Wx (66),(v1)
7093 +e2: psrad Pq,Qq | vpsrad Vx,Hx,Wx (66),(v1)
7094 +e3: pavgw Pq,Qq | vpavgw Vx,Hx,Wx (66),(v1)
7095 +e4: pmulhuw Pq,Qq | vpmulhuw Vx,Hx,Wx (66),(v1)
7096 +e5: pmulhw Pq,Qq | vpmulhw Vx,Hx,Wx (66),(v1)
7097 +e6: vcvttpd2dq Vx,Wpd (66) | vcvtdq2pd Vx,Wdq (F3) | vcvtdq2pd/qq2pd Vx,Wdq (F3),(evo) | vcvtpd2dq Vx,Wpd (F2)
7098 +e7: movntq Mq,Pq | vmovntdq Mx,Vx (66)
7099 +e8: psubsb Pq,Qq | vpsubsb Vx,Hx,Wx (66),(v1)
7100 +e9: psubsw Pq,Qq | vpsubsw Vx,Hx,Wx (66),(v1)
7101 +ea: pminsw Pq,Qq | vpminsw Vx,Hx,Wx (66),(v1)
7102 +eb: por Pq,Qq | vpor Vx,Hx,Wx (66),(v1) | vpord/q Vx,Hx,Wx (66),(evo)
7103 +ec: paddsb Pq,Qq | vpaddsb Vx,Hx,Wx (66),(v1)
7104 +ed: paddsw Pq,Qq | vpaddsw Vx,Hx,Wx (66),(v1)
7105 +ee: pmaxsw Pq,Qq | vpmaxsw Vx,Hx,Wx (66),(v1)
7106 +ef: pxor Pq,Qq | vpxor Vx,Hx,Wx (66),(v1) | vpxord/q Vx,Hx,Wx (66),(evo)
7107 +# 0x0f 0xf0-0xff
7108 +f0: vlddqu Vx,Mx (F2)
7109 +f1: psllw Pq,Qq | vpsllw Vx,Hx,Wx (66),(v1)
7110 +f2: pslld Pq,Qq | vpslld Vx,Hx,Wx (66),(v1)
7111 +f3: psllq Pq,Qq | vpsllq Vx,Hx,Wx (66),(v1)
7112 +f4: pmuludq Pq,Qq | vpmuludq Vx,Hx,Wx (66),(v1)
7113 +f5: pmaddwd Pq,Qq | vpmaddwd Vx,Hx,Wx (66),(v1)
7114 +f6: psadbw Pq,Qq | vpsadbw Vx,Hx,Wx (66),(v1)
7115 +f7: maskmovq Pq,Nq | vmaskmovdqu Vx,Ux (66),(v1)
7116 +f8: psubb Pq,Qq | vpsubb Vx,Hx,Wx (66),(v1)
7117 +f9: psubw Pq,Qq | vpsubw Vx,Hx,Wx (66),(v1)
7118 +fa: psubd Pq,Qq | vpsubd Vx,Hx,Wx (66),(v1)
7119 +fb: psubq Pq,Qq | vpsubq Vx,Hx,Wx (66),(v1)
7120 +fc: paddb Pq,Qq | vpaddb Vx,Hx,Wx (66),(v1)
7121 +fd: paddw Pq,Qq | vpaddw Vx,Hx,Wx (66),(v1)
7122 +fe: paddd Pq,Qq | vpaddd Vx,Hx,Wx (66),(v1)
7123 +ff:
7124 +EndTable
7125 +
7126 +Table: 3-byte opcode 1 (0x0f 0x38)
7127 +Referrer: 3-byte escape 1
7128 +AVXcode: 2
7129 +# 0x0f 0x38 0x00-0x0f
7130 +00: pshufb Pq,Qq | vpshufb Vx,Hx,Wx (66),(v1)
7131 +01: phaddw Pq,Qq | vphaddw Vx,Hx,Wx (66),(v1)
7132 +02: phaddd Pq,Qq | vphaddd Vx,Hx,Wx (66),(v1)
7133 +03: phaddsw Pq,Qq | vphaddsw Vx,Hx,Wx (66),(v1)
7134 +04: pmaddubsw Pq,Qq | vpmaddubsw Vx,Hx,Wx (66),(v1)
7135 +05: phsubw Pq,Qq | vphsubw Vx,Hx,Wx (66),(v1)
7136 +06: phsubd Pq,Qq | vphsubd Vx,Hx,Wx (66),(v1)
7137 +07: phsubsw Pq,Qq | vphsubsw Vx,Hx,Wx (66),(v1)
7138 +08: psignb Pq,Qq | vpsignb Vx,Hx,Wx (66),(v1)
7139 +09: psignw Pq,Qq | vpsignw Vx,Hx,Wx (66),(v1)
7140 +0a: psignd Pq,Qq | vpsignd Vx,Hx,Wx (66),(v1)
7141 +0b: pmulhrsw Pq,Qq | vpmulhrsw Vx,Hx,Wx (66),(v1)
7142 +0c: vpermilps Vx,Hx,Wx (66),(v)
7143 +0d: vpermilpd Vx,Hx,Wx (66),(v)
7144 +0e: vtestps Vx,Wx (66),(v)
7145 +0f: vtestpd Vx,Wx (66),(v)
7146 +# 0x0f 0x38 0x10-0x1f
7147 +10: pblendvb Vdq,Wdq (66) | vpsrlvw Vx,Hx,Wx (66),(evo) | vpmovuswb Wx,Vx (F3),(ev)
7148 +11: vpmovusdb Wx,Vd (F3),(ev) | vpsravw Vx,Hx,Wx (66),(ev)
7149 +12: vpmovusqb Wx,Vq (F3),(ev) | vpsllvw Vx,Hx,Wx (66),(ev)
7150 +13: vcvtph2ps Vx,Wx (66),(v) | vpmovusdw Wx,Vd (F3),(ev)
7151 +14: blendvps Vdq,Wdq (66) | vpmovusqw Wx,Vq (F3),(ev) | vprorvd/q Vx,Hx,Wx (66),(evo)
7152 +15: blendvpd Vdq,Wdq (66) | vpmovusqd Wx,Vq (F3),(ev) | vprolvd/q Vx,Hx,Wx (66),(evo)
7153 +16: vpermps Vqq,Hqq,Wqq (66),(v) | vpermps/d Vqq,Hqq,Wqq (66),(evo)
7154 +17: vptest Vx,Wx (66)
7155 +18: vbroadcastss Vx,Wd (66),(v)
7156 +19: vbroadcastsd Vqq,Wq (66),(v) | vbroadcastf32x2 Vqq,Wq (66),(evo)
7157 +1a: vbroadcastf128 Vqq,Mdq (66),(v) | vbroadcastf32x4/64x2 Vqq,Wq (66),(evo)
7158 +1b: vbroadcastf32x8/64x4 Vqq,Mdq (66),(ev)
7159 +1c: pabsb Pq,Qq | vpabsb Vx,Wx (66),(v1)
7160 +1d: pabsw Pq,Qq | vpabsw Vx,Wx (66),(v1)
7161 +1e: pabsd Pq,Qq | vpabsd Vx,Wx (66),(v1)
7162 +1f: vpabsq Vx,Wx (66),(ev)
7163 +# 0x0f 0x38 0x20-0x2f
7164 +20: vpmovsxbw Vx,Ux/Mq (66),(v1) | vpmovswb Wx,Vx (F3),(ev)
7165 +21: vpmovsxbd Vx,Ux/Md (66),(v1) | vpmovsdb Wx,Vd (F3),(ev)
7166 +22: vpmovsxbq Vx,Ux/Mw (66),(v1) | vpmovsqb Wx,Vq (F3),(ev)
7167 +23: vpmovsxwd Vx,Ux/Mq (66),(v1) | vpmovsdw Wx,Vd (F3),(ev)
7168 +24: vpmovsxwq Vx,Ux/Md (66),(v1) | vpmovsqw Wx,Vq (F3),(ev)
7169 +25: vpmovsxdq Vx,Ux/Mq (66),(v1) | vpmovsqd Wx,Vq (F3),(ev)
7170 +26: vptestmb/w Vk,Hx,Wx (66),(ev) | vptestnmb/w Vk,Hx,Wx (F3),(ev)
7171 +27: vptestmd/q Vk,Hx,Wx (66),(ev) | vptestnmd/q Vk,Hx,Wx (F3),(ev)
7172 +28: vpmuldq Vx,Hx,Wx (66),(v1) | vpmovm2b/w Vx,Uk (F3),(ev)
7173 +29: vpcmpeqq Vx,Hx,Wx (66),(v1) | vpmovb2m/w2m Vk,Ux (F3),(ev)
7174 +2a: vmovntdqa Vx,Mx (66),(v1) | vpbroadcastmb2q Vx,Uk (F3),(ev)
7175 +2b: vpackusdw Vx,Hx,Wx (66),(v1)
7176 +2c: vmaskmovps Vx,Hx,Mx (66),(v) | vscalefps/d Vx,Hx,Wx (66),(evo)
7177 +2d: vmaskmovpd Vx,Hx,Mx (66),(v) | vscalefss/d Vx,Hx,Wx (66),(evo)
7178 +2e: vmaskmovps Mx,Hx,Vx (66),(v)
7179 +2f: vmaskmovpd Mx,Hx,Vx (66),(v)
7180 +# 0x0f 0x38 0x30-0x3f
7181 +30: vpmovzxbw Vx,Ux/Mq (66),(v1) | vpmovwb Wx,Vx (F3),(ev)
7182 +31: vpmovzxbd Vx,Ux/Md (66),(v1) | vpmovdb Wx,Vd (F3),(ev)
7183 +32: vpmovzxbq Vx,Ux/Mw (66),(v1) | vpmovqb Wx,Vq (F3),(ev)
7184 +33: vpmovzxwd Vx,Ux/Mq (66),(v1) | vpmovdw Wx,Vd (F3),(ev)
7185 +34: vpmovzxwq Vx,Ux/Md (66),(v1) | vpmovqw Wx,Vq (F3),(ev)
7186 +35: vpmovzxdq Vx,Ux/Mq (66),(v1) | vpmovqd Wx,Vq (F3),(ev)
7187 +36: vpermd Vqq,Hqq,Wqq (66),(v) | vpermd/q Vqq,Hqq,Wqq (66),(evo)
7188 +37: vpcmpgtq Vx,Hx,Wx (66),(v1)
7189 +38: vpminsb Vx,Hx,Wx (66),(v1) | vpmovm2d/q Vx,Uk (F3),(ev)
7190 +39: vpminsd Vx,Hx,Wx (66),(v1) | vpminsd/q Vx,Hx,Wx (66),(evo) | vpmovd2m/q2m Vk,Ux (F3),(ev)
7191 +3a: vpminuw Vx,Hx,Wx (66),(v1) | vpbroadcastmw2d Vx,Uk (F3),(ev)
7192 +3b: vpminud Vx,Hx,Wx (66),(v1) | vpminud/q Vx,Hx,Wx (66),(evo)
7193 +3c: vpmaxsb Vx,Hx,Wx (66),(v1)
7194 +3d: vpmaxsd Vx,Hx,Wx (66),(v1) | vpmaxsd/q Vx,Hx,Wx (66),(evo)
7195 +3e: vpmaxuw Vx,Hx,Wx (66),(v1)
7196 +3f: vpmaxud Vx,Hx,Wx (66),(v1) | vpmaxud/q Vx,Hx,Wx (66),(evo)
7197 +# 0x0f 0x38 0x40-0x8f
7198 +40: vpmulld Vx,Hx,Wx (66),(v1) | vpmulld/q Vx,Hx,Wx (66),(evo)
7199 +41: vphminposuw Vdq,Wdq (66),(v1)
7200 +42: vgetexpps/d Vx,Wx (66),(ev)
7201 +43: vgetexpss/d Vx,Hx,Wx (66),(ev)
7202 +44: vplzcntd/q Vx,Wx (66),(ev)
7203 +45: vpsrlvd/q Vx,Hx,Wx (66),(v)
7204 +46: vpsravd Vx,Hx,Wx (66),(v) | vpsravd/q Vx,Hx,Wx (66),(evo)
7205 +47: vpsllvd/q Vx,Hx,Wx (66),(v)
7206 +# Skip 0x48-0x4b
7207 +4c: vrcp14ps/d Vpd,Wpd (66),(ev)
7208 +4d: vrcp14ss/d Vsd,Hpd,Wsd (66),(ev)
7209 +4e: vrsqrt14ps/d Vpd,Wpd (66),(ev)
7210 +4f: vrsqrt14ss/d Vsd,Hsd,Wsd (66),(ev)
7211 +# Skip 0x50-0x57
7212 +58: vpbroadcastd Vx,Wx (66),(v)
7213 +59: vpbroadcastq Vx,Wx (66),(v) | vbroadcasti32x2 Vx,Wx (66),(evo)
7214 +5a: vbroadcasti128 Vqq,Mdq (66),(v) | vbroadcasti32x4/64x2 Vx,Wx (66),(evo)
7215 +5b: vbroadcasti32x8/64x4 Vqq,Mdq (66),(ev)
7216 +# Skip 0x5c-0x63
7217 +64: vpblendmd/q Vx,Hx,Wx (66),(ev)
7218 +65: vblendmps/d Vx,Hx,Wx (66),(ev)
7219 +66: vpblendmb/w Vx,Hx,Wx (66),(ev)
7220 +# Skip 0x67-0x74
7221 +75: vpermi2b/w Vx,Hx,Wx (66),(ev)
7222 +76: vpermi2d/q Vx,Hx,Wx (66),(ev)
7223 +77: vpermi2ps/d Vx,Hx,Wx (66),(ev)
7224 +78: vpbroadcastb Vx,Wx (66),(v)
7225 +79: vpbroadcastw Vx,Wx (66),(v)
7226 +7a: vpbroadcastb Vx,Rv (66),(ev)
7227 +7b: vpbroadcastw Vx,Rv (66),(ev)
7228 +7c: vpbroadcastd/q Vx,Rv (66),(ev)
7229 +7d: vpermt2b/w Vx,Hx,Wx (66),(ev)
7230 +7e: vpermt2d/q Vx,Hx,Wx (66),(ev)
7231 +7f: vpermt2ps/d Vx,Hx,Wx (66),(ev)
7232 +80: INVEPT Gy,Mdq (66)
7233 +81: INVPID Gy,Mdq (66)
7234 +82: INVPCID Gy,Mdq (66)
7235 +83: vpmultishiftqb Vx,Hx,Wx (66),(ev)
7236 +88: vexpandps/d Vpd,Wpd (66),(ev)
7237 +89: vpexpandd/q Vx,Wx (66),(ev)
7238 +8a: vcompressps/d Wx,Vx (66),(ev)
7239 +8b: vpcompressd/q Wx,Vx (66),(ev)
7240 +8c: vpmaskmovd/q Vx,Hx,Mx (66),(v)
7241 +8d: vpermb/w Vx,Hx,Wx (66),(ev)
7242 +8e: vpmaskmovd/q Mx,Vx,Hx (66),(v)
7243 +# 0x0f 0x38 0x90-0xbf (FMA)
7244 +90: vgatherdd/q Vx,Hx,Wx (66),(v) | vpgatherdd/q Vx,Wx (66),(evo)
7245 +91: vgatherqd/q Vx,Hx,Wx (66),(v) | vpgatherqd/q Vx,Wx (66),(evo)
7246 +92: vgatherdps/d Vx,Hx,Wx (66),(v)
7247 +93: vgatherqps/d Vx,Hx,Wx (66),(v)
7248 +94:
7249 +95:
7250 +96: vfmaddsub132ps/d Vx,Hx,Wx (66),(v)
7251 +97: vfmsubadd132ps/d Vx,Hx,Wx (66),(v)
7252 +98: vfmadd132ps/d Vx,Hx,Wx (66),(v)
7253 +99: vfmadd132ss/d Vx,Hx,Wx (66),(v),(v1)
7254 +9a: vfmsub132ps/d Vx,Hx,Wx (66),(v)
7255 +9b: vfmsub132ss/d Vx,Hx,Wx (66),(v),(v1)
7256 +9c: vfnmadd132ps/d Vx,Hx,Wx (66),(v)
7257 +9d: vfnmadd132ss/d Vx,Hx,Wx (66),(v),(v1)
7258 +9e: vfnmsub132ps/d Vx,Hx,Wx (66),(v)
7259 +9f: vfnmsub132ss/d Vx,Hx,Wx (66),(v),(v1)
7260 +a0: vpscatterdd/q Wx,Vx (66),(ev)
7261 +a1: vpscatterqd/q Wx,Vx (66),(ev)
7262 +a2: vscatterdps/d Wx,Vx (66),(ev)
7263 +a3: vscatterqps/d Wx,Vx (66),(ev)
7264 +a6: vfmaddsub213ps/d Vx,Hx,Wx (66),(v)
7265 +a7: vfmsubadd213ps/d Vx,Hx,Wx (66),(v)
7266 +a8: vfmadd213ps/d Vx,Hx,Wx (66),(v)
7267 +a9: vfmadd213ss/d Vx,Hx,Wx (66),(v),(v1)
7268 +aa: vfmsub213ps/d Vx,Hx,Wx (66),(v)
7269 +ab: vfmsub213ss/d Vx,Hx,Wx (66),(v),(v1)
7270 +ac: vfnmadd213ps/d Vx,Hx,Wx (66),(v)
7271 +ad: vfnmadd213ss/d Vx,Hx,Wx (66),(v),(v1)
7272 +ae: vfnmsub213ps/d Vx,Hx,Wx (66),(v)
7273 +af: vfnmsub213ss/d Vx,Hx,Wx (66),(v),(v1)
7274 +b4: vpmadd52luq Vx,Hx,Wx (66),(ev)
7275 +b5: vpmadd52huq Vx,Hx,Wx (66),(ev)
7276 +b6: vfmaddsub231ps/d Vx,Hx,Wx (66),(v)
7277 +b7: vfmsubadd231ps/d Vx,Hx,Wx (66),(v)
7278 +b8: vfmadd231ps/d Vx,Hx,Wx (66),(v)
7279 +b9: vfmadd231ss/d Vx,Hx,Wx (66),(v),(v1)
7280 +ba: vfmsub231ps/d Vx,Hx,Wx (66),(v)
7281 +bb: vfmsub231ss/d Vx,Hx,Wx (66),(v),(v1)
7282 +bc: vfnmadd231ps/d Vx,Hx,Wx (66),(v)
7283 +bd: vfnmadd231ss/d Vx,Hx,Wx (66),(v),(v1)
7284 +be: vfnmsub231ps/d Vx,Hx,Wx (66),(v)
7285 +bf: vfnmsub231ss/d Vx,Hx,Wx (66),(v),(v1)
7286 +# 0x0f 0x38 0xc0-0xff
7287 +c4: vpconflictd/q Vx,Wx (66),(ev)
7288 +c6: Grp18 (1A)
7289 +c7: Grp19 (1A)
7290 +c8: sha1nexte Vdq,Wdq | vexp2ps/d Vx,Wx (66),(ev)
7291 +c9: sha1msg1 Vdq,Wdq
7292 +ca: sha1msg2 Vdq,Wdq | vrcp28ps/d Vx,Wx (66),(ev)
7293 +cb: sha256rnds2 Vdq,Wdq | vrcp28ss/d Vx,Hx,Wx (66),(ev)
7294 +cc: sha256msg1 Vdq,Wdq | vrsqrt28ps/d Vx,Wx (66),(ev)
7295 +cd: sha256msg2 Vdq,Wdq | vrsqrt28ss/d Vx,Hx,Wx (66),(ev)
7296 +db: VAESIMC Vdq,Wdq (66),(v1)
7297 +dc: VAESENC Vdq,Hdq,Wdq (66),(v1)
7298 +dd: VAESENCLAST Vdq,Hdq,Wdq (66),(v1)
7299 +de: VAESDEC Vdq,Hdq,Wdq (66),(v1)
7300 +df: VAESDECLAST Vdq,Hdq,Wdq (66),(v1)
7301 +f0: MOVBE Gy,My | MOVBE Gw,Mw (66) | CRC32 Gd,Eb (F2) | CRC32 Gd,Eb (66&F2)
7302 +f1: MOVBE My,Gy | MOVBE Mw,Gw (66) | CRC32 Gd,Ey (F2) | CRC32 Gd,Ew (66&F2)
7303 +f2: ANDN Gy,By,Ey (v)
7304 +f3: Grp17 (1A)
7305 +f5: BZHI Gy,Ey,By (v) | PEXT Gy,By,Ey (F3),(v) | PDEP Gy,By,Ey (F2),(v)
7306 +f6: ADCX Gy,Ey (66) | ADOX Gy,Ey (F3) | MULX By,Gy,rDX,Ey (F2),(v)
7307 +f7: BEXTR Gy,Ey,By (v) | SHLX Gy,Ey,By (66),(v) | SARX Gy,Ey,By (F3),(v) | SHRX Gy,Ey,By (F2),(v)
7308 +EndTable
7309 +
7310 +Table: 3-byte opcode 2 (0x0f 0x3a)
7311 +Referrer: 3-byte escape 2
7312 +AVXcode: 3
7313 +# 0x0f 0x3a 0x00-0xff
7314 +00: vpermq Vqq,Wqq,Ib (66),(v)
7315 +01: vpermpd Vqq,Wqq,Ib (66),(v)
7316 +02: vpblendd Vx,Hx,Wx,Ib (66),(v)
7317 +03: valignd/q Vx,Hx,Wx,Ib (66),(ev)
7318 +04: vpermilps Vx,Wx,Ib (66),(v)
7319 +05: vpermilpd Vx,Wx,Ib (66),(v)
7320 +06: vperm2f128 Vqq,Hqq,Wqq,Ib (66),(v)
7321 +07:
7322 +08: vroundps Vx,Wx,Ib (66) | vrndscaleps Vx,Wx,Ib (66),(evo)
7323 +09: vroundpd Vx,Wx,Ib (66) | vrndscalepd Vx,Wx,Ib (66),(evo)
7324 +0a: vroundss Vss,Wss,Ib (66),(v1) | vrndscaless Vx,Hx,Wx,Ib (66),(evo)
7325 +0b: vroundsd Vsd,Wsd,Ib (66),(v1) | vrndscalesd Vx,Hx,Wx,Ib (66),(evo)
7326 +0c: vblendps Vx,Hx,Wx,Ib (66)
7327 +0d: vblendpd Vx,Hx,Wx,Ib (66)
7328 +0e: vpblendw Vx,Hx,Wx,Ib (66),(v1)
7329 +0f: palignr Pq,Qq,Ib | vpalignr Vx,Hx,Wx,Ib (66),(v1)
7330 +14: vpextrb Rd/Mb,Vdq,Ib (66),(v1)
7331 +15: vpextrw Rd/Mw,Vdq,Ib (66),(v1)
7332 +16: vpextrd/q Ey,Vdq,Ib (66),(v1)
7333 +17: vextractps Ed,Vdq,Ib (66),(v1)
7334 +18: vinsertf128 Vqq,Hqq,Wqq,Ib (66),(v) | vinsertf32x4/64x2 Vqq,Hqq,Wqq,Ib (66),(evo)
7335 +19: vextractf128 Wdq,Vqq,Ib (66),(v) | vextractf32x4/64x2 Wdq,Vqq,Ib (66),(evo)
7336 +1a: vinsertf32x8/64x4 Vqq,Hqq,Wqq,Ib (66),(ev)
7337 +1b: vextractf32x8/64x4 Wdq,Vqq,Ib (66),(ev)
7338 +1d: vcvtps2ph Wx,Vx,Ib (66),(v)
7339 +1e: vpcmpud/q Vk,Hd,Wd,Ib (66),(ev)
7340 +1f: vpcmpd/q Vk,Hd,Wd,Ib (66),(ev)
7341 +20: vpinsrb Vdq,Hdq,Ry/Mb,Ib (66),(v1)
7342 +21: vinsertps Vdq,Hdq,Udq/Md,Ib (66),(v1)
7343 +22: vpinsrd/q Vdq,Hdq,Ey,Ib (66),(v1)
7344 +23: vshuff32x4/64x2 Vx,Hx,Wx,Ib (66),(ev)
7345 +25: vpternlogd/q Vx,Hx,Wx,Ib (66),(ev)
7346 +26: vgetmantps/d Vx,Wx,Ib (66),(ev)
7347 +27: vgetmantss/d Vx,Hx,Wx,Ib (66),(ev)
7348 +30: kshiftrb/w Vk,Uk,Ib (66),(v)
7349 +31: kshiftrd/q Vk,Uk,Ib (66),(v)
7350 +32: kshiftlb/w Vk,Uk,Ib (66),(v)
7351 +33: kshiftld/q Vk,Uk,Ib (66),(v)
7352 +38: vinserti128 Vqq,Hqq,Wqq,Ib (66),(v) | vinserti32x4/64x2 Vqq,Hqq,Wqq,Ib (66),(evo)
7353 +39: vextracti128 Wdq,Vqq,Ib (66),(v) | vextracti32x4/64x2 Wdq,Vqq,Ib (66),(evo)
7354 +3a: vinserti32x8/64x4 Vqq,Hqq,Wqq,Ib (66),(ev)
7355 +3b: vextracti32x8/64x4 Wdq,Vqq,Ib (66),(ev)
7356 +3e: vpcmpub/w Vk,Hk,Wx,Ib (66),(ev)
7357 +3f: vpcmpb/w Vk,Hk,Wx,Ib (66),(ev)
7358 +40: vdpps Vx,Hx,Wx,Ib (66)
7359 +41: vdppd Vdq,Hdq,Wdq,Ib (66),(v1)
7360 +42: vmpsadbw Vx,Hx,Wx,Ib (66),(v1) | vdbpsadbw Vx,Hx,Wx,Ib (66),(evo)
7361 +43: vshufi32x4/64x2 Vx,Hx,Wx,Ib (66),(ev)
7362 +44: vpclmulqdq Vdq,Hdq,Wdq,Ib (66),(v1)
7363 +46: vperm2i128 Vqq,Hqq,Wqq,Ib (66),(v)
7364 +4a: vblendvps Vx,Hx,Wx,Lx (66),(v)
7365 +4b: vblendvpd Vx,Hx,Wx,Lx (66),(v)
7366 +4c: vpblendvb Vx,Hx,Wx,Lx (66),(v1)
7367 +50: vrangeps/d Vx,Hx,Wx,Ib (66),(ev)
7368 +51: vrangess/d Vx,Hx,Wx,Ib (66),(ev)
7369 +54: vfixupimmps/d Vx,Hx,Wx,Ib (66),(ev)
7370 +55: vfixupimmss/d Vx,Hx,Wx,Ib (66),(ev)
7371 +56: vreduceps/d Vx,Wx,Ib (66),(ev)
7372 +57: vreducess/d Vx,Hx,Wx,Ib (66),(ev)
7373 +60: vpcmpestrm Vdq,Wdq,Ib (66),(v1)
7374 +61: vpcmpestri Vdq,Wdq,Ib (66),(v1)
7375 +62: vpcmpistrm Vdq,Wdq,Ib (66),(v1)
7376 +63: vpcmpistri Vdq,Wdq,Ib (66),(v1)
7377 +66: vfpclassps/d Vk,Wx,Ib (66),(ev)
7378 +67: vfpclassss/d Vk,Wx,Ib (66),(ev)
7379 +cc: sha1rnds4 Vdq,Wdq,Ib
7380 +df: VAESKEYGEN Vdq,Wdq,Ib (66),(v1)
7381 +f0: RORX Gy,Ey,Ib (F2),(v)
7382 +EndTable
7383 +
7384 +GrpTable: Grp1
7385 +0: ADD
7386 +1: OR
7387 +2: ADC
7388 +3: SBB
7389 +4: AND
7390 +5: SUB
7391 +6: XOR
7392 +7: CMP
7393 +EndTable
7394 +
7395 +GrpTable: Grp1A
7396 +0: POP
7397 +EndTable
7398 +
7399 +GrpTable: Grp2
7400 +0: ROL
7401 +1: ROR
7402 +2: RCL
7403 +3: RCR
7404 +4: SHL/SAL
7405 +5: SHR
7406 +6:
7407 +7: SAR
7408 +EndTable
7409 +
7410 +GrpTable: Grp3_1
7411 +0: TEST Eb,Ib
7412 +1: TEST Eb,Ib
7413 +2: NOT Eb
7414 +3: NEG Eb
7415 +4: MUL AL,Eb
7416 +5: IMUL AL,Eb
7417 +6: DIV AL,Eb
7418 +7: IDIV AL,Eb
7419 +EndTable
7420 +
7421 +GrpTable: Grp3_2
7422 +0: TEST Ev,Iz
7423 +1:
7424 +2: NOT Ev
7425 +3: NEG Ev
7426 +4: MUL rAX,Ev
7427 +5: IMUL rAX,Ev
7428 +6: DIV rAX,Ev
7429 +7: IDIV rAX,Ev
7430 +EndTable
7431 +
7432 +GrpTable: Grp4
7433 +0: INC Eb
7434 +1: DEC Eb
7435 +EndTable
7436 +
7437 +GrpTable: Grp5
7438 +0: INC Ev
7439 +1: DEC Ev
7440 +# Note: "forced64" is Intel CPU behavior (see comment about CALL insn).
7441 +2: CALLN Ev (f64)
7442 +3: CALLF Ep
7443 +4: JMPN Ev (f64)
7444 +5: JMPF Mp
7445 +6: PUSH Ev (d64)
7446 +7:
7447 +EndTable
7448 +
7449 +GrpTable: Grp6
7450 +0: SLDT Rv/Mw
7451 +1: STR Rv/Mw
7452 +2: LLDT Ew
7453 +3: LTR Ew
7454 +4: VERR Ew
7455 +5: VERW Ew
7456 +EndTable
7457 +
7458 +GrpTable: Grp7
7459 +0: SGDT Ms | VMCALL (001),(11B) | VMLAUNCH (010),(11B) | VMRESUME (011),(11B) | VMXOFF (100),(11B)
7460 +1: SIDT Ms | MONITOR (000),(11B) | MWAIT (001),(11B) | CLAC (010),(11B) | STAC (011),(11B)
7461 +2: LGDT Ms | XGETBV (000),(11B) | XSETBV (001),(11B) | VMFUNC (100),(11B) | XEND (101)(11B) | XTEST (110)(11B)
7462 +3: LIDT Ms
7463 +4: SMSW Mw/Rv
7464 +5: rdpkru (110),(11B) | wrpkru (111),(11B)
7465 +6: LMSW Ew
7466 +7: INVLPG Mb | SWAPGS (o64),(000),(11B) | RDTSCP (001),(11B)
7467 +EndTable
7468 +
7469 +GrpTable: Grp8
7470 +4: BT
7471 +5: BTS
7472 +6: BTR
7473 +7: BTC
7474 +EndTable
7475 +
7476 +GrpTable: Grp9
7477 +1: CMPXCHG8B/16B Mq/Mdq
7478 +3: xrstors
7479 +4: xsavec
7480 +5: xsaves
7481 +6: VMPTRLD Mq | VMCLEAR Mq (66) | VMXON Mq (F3) | RDRAND Rv (11B)
7482 +7: VMPTRST Mq | VMPTRST Mq (F3) | RDSEED Rv (11B)
7483 +EndTable
7484 +
7485 +GrpTable: Grp10
7486 +EndTable
7487 +
7488 +# Grp11A and Grp11B are expressed as Grp11 in Intel SDM
7489 +GrpTable: Grp11A
7490 +0: MOV Eb,Ib
7491 +7: XABORT Ib (000),(11B)
7492 +EndTable
7493 +
7494 +GrpTable: Grp11B
7495 +0: MOV Eb,Iz
7496 +7: XBEGIN Jz (000),(11B)
7497 +EndTable
7498 +
7499 +GrpTable: Grp12
7500 +2: psrlw Nq,Ib (11B) | vpsrlw Hx,Ux,Ib (66),(11B),(v1)
7501 +4: psraw Nq,Ib (11B) | vpsraw Hx,Ux,Ib (66),(11B),(v1)
7502 +6: psllw Nq,Ib (11B) | vpsllw Hx,Ux,Ib (66),(11B),(v1)
7503 +EndTable
7504 +
7505 +GrpTable: Grp13
7506 +0: vprord/q Hx,Wx,Ib (66),(ev)
7507 +1: vprold/q Hx,Wx,Ib (66),(ev)
7508 +2: psrld Nq,Ib (11B) | vpsrld Hx,Ux,Ib (66),(11B),(v1)
7509 +4: psrad Nq,Ib (11B) | vpsrad Hx,Ux,Ib (66),(11B),(v1) | vpsrad/q Hx,Ux,Ib (66),(evo)
7510 +6: pslld Nq,Ib (11B) | vpslld Hx,Ux,Ib (66),(11B),(v1)
7511 +EndTable
7512 +
7513 +GrpTable: Grp14
7514 +2: psrlq Nq,Ib (11B) | vpsrlq Hx,Ux,Ib (66),(11B),(v1)
7515 +3: vpsrldq Hx,Ux,Ib (66),(11B),(v1)
7516 +6: psllq Nq,Ib (11B) | vpsllq Hx,Ux,Ib (66),(11B),(v1)
7517 +7: vpslldq Hx,Ux,Ib (66),(11B),(v1)
7518 +EndTable
7519 +
7520 +GrpTable: Grp15
7521 +0: fxsave | RDFSBASE Ry (F3),(11B)
7522 +1: fxstor | RDGSBASE Ry (F3),(11B)
7523 +2: vldmxcsr Md (v1) | WRFSBASE Ry (F3),(11B)
7524 +3: vstmxcsr Md (v1) | WRGSBASE Ry (F3),(11B)
7525 +4: XSAVE
7526 +5: XRSTOR | lfence (11B)
7527 +6: XSAVEOPT | clwb (66) | mfence (11B)
7528 +7: clflush | clflushopt (66) | sfence (11B)
7529 +EndTable
7530 +
7531 +GrpTable: Grp16
7532 +0: prefetch NTA
7533 +1: prefetch T0
7534 +2: prefetch T1
7535 +3: prefetch T2
7536 +EndTable
7537 +
7538 +GrpTable: Grp17
7539 +1: BLSR By,Ey (v)
7540 +2: BLSMSK By,Ey (v)
7541 +3: BLSI By,Ey (v)
7542 +EndTable
7543 +
7544 +GrpTable: Grp18
7545 +1: vgatherpf0dps/d Wx (66),(ev)
7546 +2: vgatherpf1dps/d Wx (66),(ev)
7547 +5: vscatterpf0dps/d Wx (66),(ev)
7548 +6: vscatterpf1dps/d Wx (66),(ev)
7549 +EndTable
7550 +
7551 +GrpTable: Grp19
7552 +1: vgatherpf0qps/d Wx (66),(ev)
7553 +2: vgatherpf1qps/d Wx (66),(ev)
7554 +5: vscatterpf0qps/d Wx (66),(ev)
7555 +6: vscatterpf1qps/d Wx (66),(ev)
7556 +EndTable
7557 +
7558 +# AMD's Prefetch Group
7559 +GrpTable: GrpP
7560 +0: PREFETCH
7561 +1: PREFETCHW
7562 +EndTable
7563 +
7564 +GrpTable: GrpPDLK
7565 +0: MONTMUL
7566 +1: XSHA1
7567 +2: XSHA2
7568 +EndTable
7569 +
7570 +GrpTable: GrpRNG
7571 +0: xstore-rng
7572 +1: xcrypt-ecb
7573 +2: xcrypt-cbc
7574 +4: xcrypt-cfb
7575 +5: xcrypt-ofb
7576 +EndTable
7577 diff --git a/tools/objtool/arch/x86/tools/gen-insn-attr-x86.awk b/tools/objtool/arch/x86/tools/gen-insn-attr-x86.awk
7578 new file mode 100644
7579 index 000000000000..a3d2c62fd805
7580 --- /dev/null
7581 +++ b/tools/objtool/arch/x86/tools/gen-insn-attr-x86.awk
7582 @@ -0,0 +1,392 @@
7583 +#!/bin/awk -f
7584 +# gen-insn-attr-x86.awk: Instruction attribute table generator
7585 +# Written by Masami Hiramatsu <mhiramat@redhat.com>
7586 +#
7587 +# Usage: awk -f gen-insn-attr-x86.awk x86-opcode-map.txt > inat-tables.c
7588 +
7589 +# Awk implementation sanity check
7590 +function check_awk_implement() {
7591 + if (sprintf("%x", 0) != "0")
7592 + return "Your awk has a printf-format problem."
7593 + return ""
7594 +}
7595 +
7596 +# Clear working vars
7597 +function clear_vars() {
7598 + delete table
7599 + delete lptable2
7600 + delete lptable1
7601 + delete lptable3
7602 + eid = -1 # escape id
7603 + gid = -1 # group id
7604 + aid = -1 # AVX id
7605 + tname = ""
7606 +}
7607 +
7608 +BEGIN {
7609 + # Implementation error checking
7610 + awkchecked = check_awk_implement()
7611 + if (awkchecked != "") {
7612 + print "Error: " awkchecked > "/dev/stderr"
7613 + print "Please try to use gawk." > "/dev/stderr"
7614 + exit 1
7615 + }
7616 +
7617 + # Setup generating tables
7618 + print "/* x86 opcode map generated from x86-opcode-map.txt */"
7619 + print "/* Do not change this code. */\n"
7620 + ggid = 1
7621 + geid = 1
7622 + gaid = 0
7623 + delete etable
7624 + delete gtable
7625 + delete atable
7626 +
7627 + opnd_expr = "^[A-Za-z/]"
7628 + ext_expr = "^\\("
7629 + sep_expr = "^\\|$"
7630 + group_expr = "^Grp[0-9A-Za-z]+"
7631 +
7632 + imm_expr = "^[IJAOL][a-z]"
7633 + imm_flag["Ib"] = "INAT_MAKE_IMM(INAT_IMM_BYTE)"
7634 + imm_flag["Jb"] = "INAT_MAKE_IMM(INAT_IMM_BYTE)"
7635 + imm_flag["Iw"] = "INAT_MAKE_IMM(INAT_IMM_WORD)"
7636 + imm_flag["Id"] = "INAT_MAKE_IMM(INAT_IMM_DWORD)"
7637 + imm_flag["Iq"] = "INAT_MAKE_IMM(INAT_IMM_QWORD)"
7638 + imm_flag["Ap"] = "INAT_MAKE_IMM(INAT_IMM_PTR)"
7639 + imm_flag["Iz"] = "INAT_MAKE_IMM(INAT_IMM_VWORD32)"
7640 + imm_flag["Jz"] = "INAT_MAKE_IMM(INAT_IMM_VWORD32)"
7641 + imm_flag["Iv"] = "INAT_MAKE_IMM(INAT_IMM_VWORD)"
7642 + imm_flag["Ob"] = "INAT_MOFFSET"
7643 + imm_flag["Ov"] = "INAT_MOFFSET"
7644 + imm_flag["Lx"] = "INAT_MAKE_IMM(INAT_IMM_BYTE)"
7645 +
7646 + modrm_expr = "^([CDEGMNPQRSUVW/][a-z]+|NTA|T[012])"
7647 + force64_expr = "\\([df]64\\)"
7648 + rex_expr = "^REX(\\.[XRWB]+)*"
7649 + fpu_expr = "^ESC" # TODO
7650 +
7651 + lprefix1_expr = "\\((66|!F3)\\)"
7652 + lprefix2_expr = "\\(F3\\)"
7653 + lprefix3_expr = "\\((F2|!F3|66\\&F2)\\)"
7654 + lprefix_expr = "\\((66|F2|F3)\\)"
7655 + max_lprefix = 4
7656 +
7657 + # All opcodes starting with lower-case 'v', 'k' or with (v1) superscript
7658 + # accepts VEX prefix
7659 + vexok_opcode_expr = "^[vk].*"
7660 + vexok_expr = "\\(v1\\)"
7661 + # All opcodes with (v) superscript supports *only* VEX prefix
7662 + vexonly_expr = "\\(v\\)"
7663 + # All opcodes with (ev) superscript supports *only* EVEX prefix
7664 + evexonly_expr = "\\(ev\\)"
7665 +
7666 + prefix_expr = "\\(Prefix\\)"
7667 + prefix_num["Operand-Size"] = "INAT_PFX_OPNDSZ"
7668 + prefix_num["REPNE"] = "INAT_PFX_REPNE"
7669 + prefix_num["REP/REPE"] = "INAT_PFX_REPE"
7670 + prefix_num["XACQUIRE"] = "INAT_PFX_REPNE"
7671 + prefix_num["XRELEASE"] = "INAT_PFX_REPE"
7672 + prefix_num["LOCK"] = "INAT_PFX_LOCK"
7673 + prefix_num["SEG=CS"] = "INAT_PFX_CS"
7674 + prefix_num["SEG=DS"] = "INAT_PFX_DS"
7675 + prefix_num["SEG=ES"] = "INAT_PFX_ES"
7676 + prefix_num["SEG=FS"] = "INAT_PFX_FS"
7677 + prefix_num["SEG=GS"] = "INAT_PFX_GS"
7678 + prefix_num["SEG=SS"] = "INAT_PFX_SS"
7679 + prefix_num["Address-Size"] = "INAT_PFX_ADDRSZ"
7680 + prefix_num["VEX+1byte"] = "INAT_PFX_VEX2"
7681 + prefix_num["VEX+2byte"] = "INAT_PFX_VEX3"
7682 + prefix_num["EVEX"] = "INAT_PFX_EVEX"
7683 +
7684 + clear_vars()
7685 +}
7686 +
7687 +function semantic_error(msg) {
7688 + print "Semantic error at " NR ": " msg > "/dev/stderr"
7689 + exit 1
7690 +}
7691 +
7692 +function debug(msg) {
7693 + print "DEBUG: " msg
7694 +}
7695 +
7696 +function array_size(arr, i,c) {
7697 + c = 0
7698 + for (i in arr)
7699 + c++
7700 + return c
7701 +}
7702 +
7703 +/^Table:/ {
7704 + print "/* " $0 " */"
7705 + if (tname != "")
7706 + semantic_error("Hit Table: before EndTable:.");
7707 +}
7708 +
7709 +/^Referrer:/ {
7710 + if (NF != 1) {
7711 + # escape opcode table
7712 + ref = ""
7713 + for (i = 2; i <= NF; i++)
7714 + ref = ref $i
7715 + eid = escape[ref]
7716 + tname = sprintf("inat_escape_table_%d", eid)
7717 + }
7718 +}
7719 +
7720 +/^AVXcode:/ {
7721 + if (NF != 1) {
7722 + # AVX/escape opcode table
7723 + aid = $2
7724 + if (gaid <= aid)
7725 + gaid = aid + 1
7726 + if (tname == "") # AVX only opcode table
7727 + tname = sprintf("inat_avx_table_%d", $2)
7728 + }
7729 + if (aid == -1 && eid == -1) # primary opcode table
7730 + tname = "inat_primary_table"
7731 +}
7732 +
7733 +/^GrpTable:/ {
7734 + print "/* " $0 " */"
7735 + if (!($2 in group))
7736 + semantic_error("No group: " $2 )
7737 + gid = group[$2]
7738 + tname = "inat_group_table_" gid
7739 +}
7740 +
7741 +function print_table(tbl,name,fmt,n)
7742 +{
7743 + print "const insn_attr_t " name " = {"
7744 + for (i = 0; i < n; i++) {
7745 + id = sprintf(fmt, i)
7746 + if (tbl[id])
7747 + print " [" id "] = " tbl[id] ","
7748 + }
7749 + print "};"
7750 +}
7751 +
7752 +/^EndTable/ {
7753 + if (gid != -1) {
7754 + # print group tables
7755 + if (array_size(table) != 0) {
7756 + print_table(table, tname "[INAT_GROUP_TABLE_SIZE]",
7757 + "0x%x", 8)
7758 + gtable[gid,0] = tname
7759 + }
7760 + if (array_size(lptable1) != 0) {
7761 + print_table(lptable1, tname "_1[INAT_GROUP_TABLE_SIZE]",
7762 + "0x%x", 8)
7763 + gtable[gid,1] = tname "_1"
7764 + }
7765 + if (array_size(lptable2) != 0) {
7766 + print_table(lptable2, tname "_2[INAT_GROUP_TABLE_SIZE]",
7767 + "0x%x", 8)
7768 + gtable[gid,2] = tname "_2"
7769 + }
7770 + if (array_size(lptable3) != 0) {
7771 + print_table(lptable3, tname "_3[INAT_GROUP_TABLE_SIZE]",
7772 + "0x%x", 8)
7773 + gtable[gid,3] = tname "_3"
7774 + }
7775 + } else {
7776 + # print primary/escaped tables
7777 + if (array_size(table) != 0) {
7778 + print_table(table, tname "[INAT_OPCODE_TABLE_SIZE]",
7779 + "0x%02x", 256)
7780 + etable[eid,0] = tname
7781 + if (aid >= 0)
7782 + atable[aid,0] = tname
7783 + }
7784 + if (array_size(lptable1) != 0) {
7785 + print_table(lptable1,tname "_1[INAT_OPCODE_TABLE_SIZE]",
7786 + "0x%02x", 256)
7787 + etable[eid,1] = tname "_1"
7788 + if (aid >= 0)
7789 + atable[aid,1] = tname "_1"
7790 + }
7791 + if (array_size(lptable2) != 0) {
7792 + print_table(lptable2,tname "_2[INAT_OPCODE_TABLE_SIZE]",
7793 + "0x%02x", 256)
7794 + etable[eid,2] = tname "_2"
7795 + if (aid >= 0)
7796 + atable[aid,2] = tname "_2"
7797 + }
7798 + if (array_size(lptable3) != 0) {
7799 + print_table(lptable3,tname "_3[INAT_OPCODE_TABLE_SIZE]",
7800 + "0x%02x", 256)
7801 + etable[eid,3] = tname "_3"
7802 + if (aid >= 0)
7803 + atable[aid,3] = tname "_3"
7804 + }
7805 + }
7806 + print ""
7807 + clear_vars()
7808 +}
7809 +
7810 +function add_flags(old,new) {
7811 + if (old && new)
7812 + return old " | " new
7813 + else if (old)
7814 + return old
7815 + else
7816 + return new
7817 +}
7818 +
7819 +# convert operands to flags.
7820 +function convert_operands(count,opnd, i,j,imm,mod)
7821 +{
7822 + imm = null
7823 + mod = null
7824 + for (j = 1; j <= count; j++) {
7825 + i = opnd[j]
7826 + if (match(i, imm_expr) == 1) {
7827 + if (!imm_flag[i])
7828 + semantic_error("Unknown imm opnd: " i)
7829 + if (imm) {
7830 + if (i != "Ib")
7831 + semantic_error("Second IMM error")
7832 + imm = add_flags(imm, "INAT_SCNDIMM")
7833 + } else
7834 + imm = imm_flag[i]
7835 + } else if (match(i, modrm_expr))
7836 + mod = "INAT_MODRM"
7837 + }
7838 + return add_flags(imm, mod)
7839 +}
7840 +
7841 +/^[0-9a-f]+\:/ {
7842 + if (NR == 1)
7843 + next
7844 + # get index
7845 + idx = "0x" substr($1, 1, index($1,":") - 1)
7846 + if (idx in table)
7847 + semantic_error("Redefine " idx " in " tname)
7848 +
7849 + # check if escaped opcode
7850 + if ("escape" == $2) {
7851 + if ($3 != "#")
7852 + semantic_error("No escaped name")
7853 + ref = ""
7854 + for (i = 4; i <= NF; i++)
7855 + ref = ref $i
7856 + if (ref in escape)
7857 + semantic_error("Redefine escape (" ref ")")
7858 + escape[ref] = geid
7859 + geid++
7860 + table[idx] = "INAT_MAKE_ESCAPE(" escape[ref] ")"
7861 + next
7862 + }
7863 +
7864 + variant = null
7865 + # converts
7866 + i = 2
7867 + while (i <= NF) {
7868 + opcode = $(i++)
7869 + delete opnds
7870 + ext = null
7871 + flags = null
7872 + opnd = null
7873 + # parse one opcode
7874 + if (match($i, opnd_expr)) {
7875 + opnd = $i
7876 + count = split($(i++), opnds, ",")
7877 + flags = convert_operands(count, opnds)
7878 + }
7879 + if (match($i, ext_expr))
7880 + ext = $(i++)
7881 + if (match($i, sep_expr))
7882 + i++
7883 + else if (i < NF)
7884 + semantic_error($i " is not a separator")
7885 +
7886 + # check if group opcode
7887 + if (match(opcode, group_expr)) {
7888 + if (!(opcode in group)) {
7889 + group[opcode] = ggid
7890 + ggid++
7891 + }
7892 + flags = add_flags(flags, "INAT_MAKE_GROUP(" group[opcode] ")")
7893 + }
7894 + # check force(or default) 64bit
7895 + if (match(ext, force64_expr))
7896 + flags = add_flags(flags, "INAT_FORCE64")
7897 +
7898 + # check REX prefix
7899 + if (match(opcode, rex_expr))
7900 + flags = add_flags(flags, "INAT_MAKE_PREFIX(INAT_PFX_REX)")
7901 +
7902 + # check coprocessor escape : TODO
7903 + if (match(opcode, fpu_expr))
7904 + flags = add_flags(flags, "INAT_MODRM")
7905 +
7906 + # check VEX codes
7907 + if (match(ext, evexonly_expr))
7908 + flags = add_flags(flags, "INAT_VEXOK | INAT_EVEXONLY")
7909 + else if (match(ext, vexonly_expr))
7910 + flags = add_flags(flags, "INAT_VEXOK | INAT_VEXONLY")
7911 + else if (match(ext, vexok_expr) || match(opcode, vexok_opcode_expr))
7912 + flags = add_flags(flags, "INAT_VEXOK")
7913 +
7914 + # check prefixes
7915 + if (match(ext, prefix_expr)) {
7916 + if (!prefix_num[opcode])
7917 + semantic_error("Unknown prefix: " opcode)
7918 + flags = add_flags(flags, "INAT_MAKE_PREFIX(" prefix_num[opcode] ")")
7919 + }
7920 + if (length(flags) == 0)
7921 + continue
7922 + # check if last prefix
7923 + if (match(ext, lprefix1_expr)) {
7924 + lptable1[idx] = add_flags(lptable1[idx],flags)
7925 + variant = "INAT_VARIANT"
7926 + }
7927 + if (match(ext, lprefix2_expr)) {
7928 + lptable2[idx] = add_flags(lptable2[idx],flags)
7929 + variant = "INAT_VARIANT"
7930 + }
7931 + if (match(ext, lprefix3_expr)) {
7932 + lptable3[idx] = add_flags(lptable3[idx],flags)
7933 + variant = "INAT_VARIANT"
7934 + }
7935 + if (!match(ext, lprefix_expr)){
7936 + table[idx] = add_flags(table[idx],flags)
7937 + }
7938 + }
7939 + if (variant)
7940 + table[idx] = add_flags(table[idx],variant)
7941 +}
7942 +
7943 +END {
7944 + if (awkchecked != "")
7945 + exit 1
7946 + # print escape opcode map's array
7947 + print "/* Escape opcode map array */"
7948 + print "const insn_attr_t * const inat_escape_tables[INAT_ESC_MAX + 1]" \
7949 + "[INAT_LSTPFX_MAX + 1] = {"
7950 + for (i = 0; i < geid; i++)
7951 + for (j = 0; j < max_lprefix; j++)
7952 + if (etable[i,j])
7953 + print " ["i"]["j"] = "etable[i,j]","
7954 + print "};\n"
7955 + # print group opcode map's array
7956 + print "/* Group opcode map array */"
7957 + print "const insn_attr_t * const inat_group_tables[INAT_GRP_MAX + 1]"\
7958 + "[INAT_LSTPFX_MAX + 1] = {"
7959 + for (i = 0; i < ggid; i++)
7960 + for (j = 0; j < max_lprefix; j++)
7961 + if (gtable[i,j])
7962 + print " ["i"]["j"] = "gtable[i,j]","
7963 + print "};\n"
7964 + # print AVX opcode map's array
7965 + print "/* AVX opcode map array */"
7966 + print "const insn_attr_t * const inat_avx_tables[X86_VEX_M_MAX + 1]"\
7967 + "[INAT_LSTPFX_MAX + 1] = {"
7968 + for (i = 0; i < gaid; i++)
7969 + for (j = 0; j < max_lprefix; j++)
7970 + if (atable[i,j])
7971 + print " ["i"]["j"] = "atable[i,j]","
7972 + print "};"
7973 +}
7974 +
7975 diff --git a/tools/objtool/builtin-check.c b/tools/objtool/builtin-check.c
7976 index a688a857a7ae..694abc628e9b 100644
7977 --- a/tools/objtool/builtin-check.c
7978 +++ b/tools/objtool/builtin-check.c
7979 @@ -1,5 +1,5 @@
7980 /*
7981 - * Copyright (C) 2015 Josh Poimboeuf <jpoimboe@redhat.com>
7982 + * Copyright (C) 2015-2017 Josh Poimboeuf <jpoimboe@redhat.com>
7983 *
7984 * This program is free software; you can redistribute it and/or
7985 * modify it under the terms of the GNU General Public License
7986 @@ -25,1300 +25,35 @@
7987 * For more information, see tools/objtool/Documentation/stack-validation.txt.
7988 */
7989
7990 -#include <string.h>
7991 -#include <stdlib.h>
7992 #include <subcmd/parse-options.h>
7993 -
7994 #include "builtin.h"
7995 -#include "elf.h"
7996 -#include "special.h"
7997 -#include "arch.h"
7998 -#include "warn.h"
7999 -
8000 -#include <linux/hashtable.h>
8001 -
8002 -#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
8003 -
8004 -#define STATE_FP_SAVED 0x1
8005 -#define STATE_FP_SETUP 0x2
8006 -#define STATE_FENTRY 0x4
8007 -
8008 -struct instruction {
8009 - struct list_head list;
8010 - struct hlist_node hash;
8011 - struct section *sec;
8012 - unsigned long offset;
8013 - unsigned int len, state;
8014 - unsigned char type;
8015 - unsigned long immediate;
8016 - bool alt_group, visited, ignore_alts;
8017 - struct symbol *call_dest;
8018 - struct instruction *jump_dest;
8019 - struct list_head alts;
8020 - struct symbol *func;
8021 -};
8022 -
8023 -struct alternative {
8024 - struct list_head list;
8025 - struct instruction *insn;
8026 -};
8027 -
8028 -struct objtool_file {
8029 - struct elf *elf;
8030 - struct list_head insn_list;
8031 - DECLARE_HASHTABLE(insn_hash, 16);
8032 - struct section *rodata, *whitelist;
8033 - bool ignore_unreachables, c_file;
8034 -};
8035 -
8036 -const char *objname;
8037 -static bool nofp;
8038 -
8039 -static struct instruction *find_insn(struct objtool_file *file,
8040 - struct section *sec, unsigned long offset)
8041 -{
8042 - struct instruction *insn;
8043 -
8044 - hash_for_each_possible(file->insn_hash, insn, hash, offset)
8045 - if (insn->sec == sec && insn->offset == offset)
8046 - return insn;
8047 -
8048 - return NULL;
8049 -}
8050 -
8051 -static struct instruction *next_insn_same_sec(struct objtool_file *file,
8052 - struct instruction *insn)
8053 -{
8054 - struct instruction *next = list_next_entry(insn, list);
8055 -
8056 - if (&next->list == &file->insn_list || next->sec != insn->sec)
8057 - return NULL;
8058 -
8059 - return next;
8060 -}
8061 -
8062 -static bool gcov_enabled(struct objtool_file *file)
8063 -{
8064 - struct section *sec;
8065 - struct symbol *sym;
8066 -
8067 - list_for_each_entry(sec, &file->elf->sections, list)
8068 - list_for_each_entry(sym, &sec->symbol_list, list)
8069 - if (!strncmp(sym->name, "__gcov_.", 8))
8070 - return true;
8071 -
8072 - return false;
8073 -}
8074 -
8075 -#define for_each_insn(file, insn) \
8076 - list_for_each_entry(insn, &file->insn_list, list)
8077 -
8078 -#define func_for_each_insn(file, func, insn) \
8079 - for (insn = find_insn(file, func->sec, func->offset); \
8080 - insn && &insn->list != &file->insn_list && \
8081 - insn->sec == func->sec && \
8082 - insn->offset < func->offset + func->len; \
8083 - insn = list_next_entry(insn, list))
8084 -
8085 -#define func_for_each_insn_continue_reverse(file, func, insn) \
8086 - for (insn = list_prev_entry(insn, list); \
8087 - &insn->list != &file->insn_list && \
8088 - insn->sec == func->sec && insn->offset >= func->offset; \
8089 - insn = list_prev_entry(insn, list))
8090 -
8091 -#define sec_for_each_insn_from(file, insn) \
8092 - for (; insn; insn = next_insn_same_sec(file, insn))
8093 -
8094 -
8095 -/*
8096 - * Check if the function has been manually whitelisted with the
8097 - * STACK_FRAME_NON_STANDARD macro, or if it should be automatically whitelisted
8098 - * due to its use of a context switching instruction.
8099 - */
8100 -static bool ignore_func(struct objtool_file *file, struct symbol *func)
8101 -{
8102 - struct rela *rela;
8103 - struct instruction *insn;
8104 -
8105 - /* check for STACK_FRAME_NON_STANDARD */
8106 - if (file->whitelist && file->whitelist->rela)
8107 - list_for_each_entry(rela, &file->whitelist->rela->rela_list, list) {
8108 - if (rela->sym->type == STT_SECTION &&
8109 - rela->sym->sec == func->sec &&
8110 - rela->addend == func->offset)
8111 - return true;
8112 - if (rela->sym->type == STT_FUNC && rela->sym == func)
8113 - return true;
8114 - }
8115 -
8116 - /* check if it has a context switching instruction */
8117 - func_for_each_insn(file, func, insn)
8118 - if (insn->type == INSN_CONTEXT_SWITCH)
8119 - return true;
8120 -
8121 - return false;
8122 -}
8123 -
8124 -/*
8125 - * This checks to see if the given function is a "noreturn" function.
8126 - *
8127 - * For global functions which are outside the scope of this object file, we
8128 - * have to keep a manual list of them.
8129 - *
8130 - * For local functions, we have to detect them manually by simply looking for
8131 - * the lack of a return instruction.
8132 - *
8133 - * Returns:
8134 - * -1: error
8135 - * 0: no dead end
8136 - * 1: dead end
8137 - */
8138 -static int __dead_end_function(struct objtool_file *file, struct symbol *func,
8139 - int recursion)
8140 -{
8141 - int i;
8142 - struct instruction *insn;
8143 - bool empty = true;
8144 -
8145 - /*
8146 - * Unfortunately these have to be hard coded because the noreturn
8147 - * attribute isn't provided in ELF data.
8148 - */
8149 - static const char * const global_noreturns[] = {
8150 - "__stack_chk_fail",
8151 - "panic",
8152 - "do_exit",
8153 - "do_task_dead",
8154 - "__module_put_and_exit",
8155 - "complete_and_exit",
8156 - "kvm_spurious_fault",
8157 - "__reiserfs_panic",
8158 - "lbug_with_loc"
8159 - };
8160 -
8161 - if (func->bind == STB_WEAK)
8162 - return 0;
8163 -
8164 - if (func->bind == STB_GLOBAL)
8165 - for (i = 0; i < ARRAY_SIZE(global_noreturns); i++)
8166 - if (!strcmp(func->name, global_noreturns[i]))
8167 - return 1;
8168 -
8169 - if (!func->sec)
8170 - return 0;
8171 -
8172 - func_for_each_insn(file, func, insn) {
8173 - empty = false;
8174 -
8175 - if (insn->type == INSN_RETURN)
8176 - return 0;
8177 - }
8178 -
8179 - if (empty)
8180 - return 0;
8181 -
8182 - /*
8183 - * A function can have a sibling call instead of a return. In that
8184 - * case, the function's dead-end status depends on whether the target
8185 - * of the sibling call returns.
8186 - */
8187 - func_for_each_insn(file, func, insn) {
8188 - if (insn->sec != func->sec ||
8189 - insn->offset >= func->offset + func->len)
8190 - break;
8191 -
8192 - if (insn->type == INSN_JUMP_UNCONDITIONAL) {
8193 - struct instruction *dest = insn->jump_dest;
8194 - struct symbol *dest_func;
8195 -
8196 - if (!dest)
8197 - /* sibling call to another file */
8198 - return 0;
8199 -
8200 - if (dest->sec != func->sec ||
8201 - dest->offset < func->offset ||
8202 - dest->offset >= func->offset + func->len) {
8203 - /* local sibling call */
8204 - dest_func = find_symbol_by_offset(dest->sec,
8205 - dest->offset);
8206 - if (!dest_func)
8207 - continue;
8208 -
8209 - if (recursion == 5) {
8210 - WARN_FUNC("infinite recursion (objtool bug!)",
8211 - dest->sec, dest->offset);
8212 - return -1;
8213 - }
8214 -
8215 - return __dead_end_function(file, dest_func,
8216 - recursion + 1);
8217 - }
8218 - }
8219 -
8220 - if (insn->type == INSN_JUMP_DYNAMIC && list_empty(&insn->alts))
8221 - /* sibling call */
8222 - return 0;
8223 - }
8224 -
8225 - return 1;
8226 -}
8227 -
8228 -static int dead_end_function(struct objtool_file *file, struct symbol *func)
8229 -{
8230 - return __dead_end_function(file, func, 0);
8231 -}
8232 -
8233 -/*
8234 - * Call the arch-specific instruction decoder for all the instructions and add
8235 - * them to the global instruction list.
8236 - */
8237 -static int decode_instructions(struct objtool_file *file)
8238 -{
8239 - struct section *sec;
8240 - struct symbol *func;
8241 - unsigned long offset;
8242 - struct instruction *insn;
8243 - int ret;
8244 -
8245 - list_for_each_entry(sec, &file->elf->sections, list) {
8246 -
8247 - if (!(sec->sh.sh_flags & SHF_EXECINSTR))
8248 - continue;
8249 -
8250 - for (offset = 0; offset < sec->len; offset += insn->len) {
8251 - insn = malloc(sizeof(*insn));
8252 - memset(insn, 0, sizeof(*insn));
8253 -
8254 - INIT_LIST_HEAD(&insn->alts);
8255 - insn->sec = sec;
8256 - insn->offset = offset;
8257 -
8258 - ret = arch_decode_instruction(file->elf, sec, offset,
8259 - sec->len - offset,
8260 - &insn->len, &insn->type,
8261 - &insn->immediate);
8262 - if (ret)
8263 - return ret;
8264 -
8265 - if (!insn->type || insn->type > INSN_LAST) {
8266 - WARN_FUNC("invalid instruction type %d",
8267 - insn->sec, insn->offset, insn->type);
8268 - return -1;
8269 - }
8270 -
8271 - hash_add(file->insn_hash, &insn->hash, insn->offset);
8272 - list_add_tail(&insn->list, &file->insn_list);
8273 - }
8274 -
8275 - list_for_each_entry(func, &sec->symbol_list, list) {
8276 - if (func->type != STT_FUNC)
8277 - continue;
8278 -
8279 - if (!find_insn(file, sec, func->offset)) {
8280 - WARN("%s(): can't find starting instruction",
8281 - func->name);
8282 - return -1;
8283 - }
8284 -
8285 - func_for_each_insn(file, func, insn)
8286 - if (!insn->func)
8287 - insn->func = func;
8288 - }
8289 - }
8290 -
8291 - return 0;
8292 -}
8293 -
8294 -/*
8295 - * Warnings shouldn't be reported for ignored functions.
8296 - */
8297 -static void add_ignores(struct objtool_file *file)
8298 -{
8299 - struct instruction *insn;
8300 - struct section *sec;
8301 - struct symbol *func;
8302 -
8303 - list_for_each_entry(sec, &file->elf->sections, list) {
8304 - list_for_each_entry(func, &sec->symbol_list, list) {
8305 - if (func->type != STT_FUNC)
8306 - continue;
8307 -
8308 - if (!ignore_func(file, func))
8309 - continue;
8310 -
8311 - func_for_each_insn(file, func, insn)
8312 - insn->visited = true;
8313 - }
8314 - }
8315 -}
8316 -
8317 -/*
8318 - * FIXME: For now, just ignore any alternatives which add retpolines. This is
8319 - * a temporary hack, as it doesn't allow ORC to unwind from inside a retpoline.
8320 - * But it at least allows objtool to understand the control flow *around* the
8321 - * retpoline.
8322 - */
8323 -static int add_nospec_ignores(struct objtool_file *file)
8324 -{
8325 - struct section *sec;
8326 - struct rela *rela;
8327 - struct instruction *insn;
8328 -
8329 - sec = find_section_by_name(file->elf, ".rela.discard.nospec");
8330 - if (!sec)
8331 - return 0;
8332 -
8333 - list_for_each_entry(rela, &sec->rela_list, list) {
8334 - if (rela->sym->type != STT_SECTION) {
8335 - WARN("unexpected relocation symbol type in %s", sec->name);
8336 - return -1;
8337 - }
8338 -
8339 - insn = find_insn(file, rela->sym->sec, rela->addend);
8340 - if (!insn) {
8341 - WARN("bad .discard.nospec entry");
8342 - return -1;
8343 - }
8344 -
8345 - insn->ignore_alts = true;
8346 - }
8347 -
8348 - return 0;
8349 -}
8350 -
8351 -/*
8352 - * Find the destination instructions for all jumps.
8353 - */
8354 -static int add_jump_destinations(struct objtool_file *file)
8355 -{
8356 - struct instruction *insn;
8357 - struct rela *rela;
8358 - struct section *dest_sec;
8359 - unsigned long dest_off;
8360 -
8361 - for_each_insn(file, insn) {
8362 - if (insn->type != INSN_JUMP_CONDITIONAL &&
8363 - insn->type != INSN_JUMP_UNCONDITIONAL)
8364 - continue;
8365 -
8366 - /* skip ignores */
8367 - if (insn->visited)
8368 - continue;
8369 -
8370 - rela = find_rela_by_dest_range(insn->sec, insn->offset,
8371 - insn->len);
8372 - if (!rela) {
8373 - dest_sec = insn->sec;
8374 - dest_off = insn->offset + insn->len + insn->immediate;
8375 - } else if (rela->sym->type == STT_SECTION) {
8376 - dest_sec = rela->sym->sec;
8377 - dest_off = rela->addend + 4;
8378 - } else if (rela->sym->sec->idx) {
8379 - dest_sec = rela->sym->sec;
8380 - dest_off = rela->sym->sym.st_value + rela->addend + 4;
8381 - } else if (strstr(rela->sym->name, "_indirect_thunk_")) {
8382 - /*
8383 - * Retpoline jumps are really dynamic jumps in
8384 - * disguise, so convert them accordingly.
8385 - */
8386 - insn->type = INSN_JUMP_DYNAMIC;
8387 - continue;
8388 - } else {
8389 - /* sibling call */
8390 - insn->jump_dest = 0;
8391 - continue;
8392 - }
8393 -
8394 - insn->jump_dest = find_insn(file, dest_sec, dest_off);
8395 - if (!insn->jump_dest) {
8396 -
8397 - /*
8398 - * This is a special case where an alt instruction
8399 - * jumps past the end of the section. These are
8400 - * handled later in handle_group_alt().
8401 - */
8402 - if (!strcmp(insn->sec->name, ".altinstr_replacement"))
8403 - continue;
8404 -
8405 - WARN_FUNC("can't find jump dest instruction at %s+0x%lx",
8406 - insn->sec, insn->offset, dest_sec->name,
8407 - dest_off);
8408 - return -1;
8409 - }
8410 - }
8411 -
8412 - return 0;
8413 -}
8414 -
8415 -/*
8416 - * Find the destination instructions for all calls.
8417 - */
8418 -static int add_call_destinations(struct objtool_file *file)
8419 -{
8420 - struct instruction *insn;
8421 - unsigned long dest_off;
8422 - struct rela *rela;
8423 -
8424 - for_each_insn(file, insn) {
8425 - if (insn->type != INSN_CALL)
8426 - continue;
8427 -
8428 - rela = find_rela_by_dest_range(insn->sec, insn->offset,
8429 - insn->len);
8430 - if (!rela) {
8431 - dest_off = insn->offset + insn->len + insn->immediate;
8432 - insn->call_dest = find_symbol_by_offset(insn->sec,
8433 - dest_off);
8434 - /*
8435 - * FIXME: Thanks to retpolines, it's now considered
8436 - * normal for a function to call within itself. So
8437 - * disable this warning for now.
8438 - */
8439 -#if 0
8440 - if (!insn->call_dest) {
8441 - WARN_FUNC("can't find call dest symbol at offset 0x%lx",
8442 - insn->sec, insn->offset, dest_off);
8443 - return -1;
8444 - }
8445 -#endif
8446 - } else if (rela->sym->type == STT_SECTION) {
8447 - insn->call_dest = find_symbol_by_offset(rela->sym->sec,
8448 - rela->addend+4);
8449 - if (!insn->call_dest ||
8450 - insn->call_dest->type != STT_FUNC) {
8451 - WARN_FUNC("can't find call dest symbol at %s+0x%x",
8452 - insn->sec, insn->offset,
8453 - rela->sym->sec->name,
8454 - rela->addend + 4);
8455 - return -1;
8456 - }
8457 - } else
8458 - insn->call_dest = rela->sym;
8459 - }
8460 -
8461 - return 0;
8462 -}
8463 -
8464 -/*
8465 - * The .alternatives section requires some extra special care, over and above
8466 - * what other special sections require:
8467 - *
8468 - * 1. Because alternatives are patched in-place, we need to insert a fake jump
8469 - * instruction at the end so that validate_branch() skips all the original
8470 - * replaced instructions when validating the new instruction path.
8471 - *
8472 - * 2. An added wrinkle is that the new instruction length might be zero. In
8473 - * that case the old instructions are replaced with noops. We simulate that
8474 - * by creating a fake jump as the only new instruction.
8475 - *
8476 - * 3. In some cases, the alternative section includes an instruction which
8477 - * conditionally jumps to the _end_ of the entry. We have to modify these
8478 - * jumps' destinations to point back to .text rather than the end of the
8479 - * entry in .altinstr_replacement.
8480 - *
8481 - * 4. It has been requested that we don't validate the !POPCNT feature path
8482 - * which is a "very very small percentage of machines".
8483 - */
8484 -static int handle_group_alt(struct objtool_file *file,
8485 - struct special_alt *special_alt,
8486 - struct instruction *orig_insn,
8487 - struct instruction **new_insn)
8488 -{
8489 - struct instruction *last_orig_insn, *last_new_insn, *insn, *fake_jump;
8490 - unsigned long dest_off;
8491 -
8492 - last_orig_insn = NULL;
8493 - insn = orig_insn;
8494 - sec_for_each_insn_from(file, insn) {
8495 - if (insn->offset >= special_alt->orig_off + special_alt->orig_len)
8496 - break;
8497 -
8498 - if (special_alt->skip_orig)
8499 - insn->type = INSN_NOP;
8500 -
8501 - insn->alt_group = true;
8502 - last_orig_insn = insn;
8503 - }
8504 -
8505 - if (!next_insn_same_sec(file, last_orig_insn)) {
8506 - WARN("%s: don't know how to handle alternatives at end of section",
8507 - special_alt->orig_sec->name);
8508 - return -1;
8509 - }
8510 -
8511 - fake_jump = malloc(sizeof(*fake_jump));
8512 - if (!fake_jump) {
8513 - WARN("malloc failed");
8514 - return -1;
8515 - }
8516 - memset(fake_jump, 0, sizeof(*fake_jump));
8517 - INIT_LIST_HEAD(&fake_jump->alts);
8518 - fake_jump->sec = special_alt->new_sec;
8519 - fake_jump->offset = -1;
8520 - fake_jump->type = INSN_JUMP_UNCONDITIONAL;
8521 - fake_jump->jump_dest = list_next_entry(last_orig_insn, list);
8522 -
8523 - if (!special_alt->new_len) {
8524 - *new_insn = fake_jump;
8525 - return 0;
8526 - }
8527 -
8528 - last_new_insn = NULL;
8529 - insn = *new_insn;
8530 - sec_for_each_insn_from(file, insn) {
8531 - if (insn->offset >= special_alt->new_off + special_alt->new_len)
8532 - break;
8533 -
8534 - last_new_insn = insn;
8535 -
8536 - if (insn->type != INSN_JUMP_CONDITIONAL &&
8537 - insn->type != INSN_JUMP_UNCONDITIONAL)
8538 - continue;
8539 -
8540 - if (!insn->immediate)
8541 - continue;
8542 -
8543 - dest_off = insn->offset + insn->len + insn->immediate;
8544 - if (dest_off == special_alt->new_off + special_alt->new_len)
8545 - insn->jump_dest = fake_jump;
8546 -
8547 - if (!insn->jump_dest) {
8548 - WARN_FUNC("can't find alternative jump destination",
8549 - insn->sec, insn->offset);
8550 - return -1;
8551 - }
8552 - }
8553 -
8554 - if (!last_new_insn) {
8555 - WARN_FUNC("can't find last new alternative instruction",
8556 - special_alt->new_sec, special_alt->new_off);
8557 - return -1;
8558 - }
8559 -
8560 - list_add(&fake_jump->list, &last_new_insn->list);
8561 -
8562 - return 0;
8563 -}
8564 -
8565 -/*
8566 - * A jump table entry can either convert a nop to a jump or a jump to a nop.
8567 - * If the original instruction is a jump, make the alt entry an effective nop
8568 - * by just skipping the original instruction.
8569 - */
8570 -static int handle_jump_alt(struct objtool_file *file,
8571 - struct special_alt *special_alt,
8572 - struct instruction *orig_insn,
8573 - struct instruction **new_insn)
8574 -{
8575 - if (orig_insn->type == INSN_NOP)
8576 - return 0;
8577 -
8578 - if (orig_insn->type != INSN_JUMP_UNCONDITIONAL) {
8579 - WARN_FUNC("unsupported instruction at jump label",
8580 - orig_insn->sec, orig_insn->offset);
8581 - return -1;
8582 - }
8583 -
8584 - *new_insn = list_next_entry(orig_insn, list);
8585 - return 0;
8586 -}
8587 -
8588 -/*
8589 - * Read all the special sections which have alternate instructions which can be
8590 - * patched in or redirected to at runtime. Each instruction having alternate
8591 - * instruction(s) has them added to its insn->alts list, which will be
8592 - * traversed in validate_branch().
8593 - */
8594 -static int add_special_section_alts(struct objtool_file *file)
8595 -{
8596 - struct list_head special_alts;
8597 - struct instruction *orig_insn, *new_insn;
8598 - struct special_alt *special_alt, *tmp;
8599 - struct alternative *alt;
8600 - int ret;
8601 -
8602 - ret = special_get_alts(file->elf, &special_alts);
8603 - if (ret)
8604 - return ret;
8605 -
8606 - list_for_each_entry_safe(special_alt, tmp, &special_alts, list) {
8607 -
8608 - orig_insn = find_insn(file, special_alt->orig_sec,
8609 - special_alt->orig_off);
8610 - if (!orig_insn) {
8611 - WARN_FUNC("special: can't find orig instruction",
8612 - special_alt->orig_sec, special_alt->orig_off);
8613 - ret = -1;
8614 - goto out;
8615 - }
8616 -
8617 - /* Ignore retpoline alternatives. */
8618 - if (orig_insn->ignore_alts)
8619 - continue;
8620 -
8621 - new_insn = NULL;
8622 - if (!special_alt->group || special_alt->new_len) {
8623 - new_insn = find_insn(file, special_alt->new_sec,
8624 - special_alt->new_off);
8625 - if (!new_insn) {
8626 - WARN_FUNC("special: can't find new instruction",
8627 - special_alt->new_sec,
8628 - special_alt->new_off);
8629 - ret = -1;
8630 - goto out;
8631 - }
8632 - }
8633 +#include "check.h"
8634
8635 - if (special_alt->group) {
8636 - ret = handle_group_alt(file, special_alt, orig_insn,
8637 - &new_insn);
8638 - if (ret)
8639 - goto out;
8640 - } else if (special_alt->jump_or_nop) {
8641 - ret = handle_jump_alt(file, special_alt, orig_insn,
8642 - &new_insn);
8643 - if (ret)
8644 - goto out;
8645 - }
8646 +bool no_fp, no_unreachable, retpoline, module;
8647
8648 - alt = malloc(sizeof(*alt));
8649 - if (!alt) {
8650 - WARN("malloc failed");
8651 - ret = -1;
8652 - goto out;
8653 - }
8654 -
8655 - alt->insn = new_insn;
8656 - list_add_tail(&alt->list, &orig_insn->alts);
8657 -
8658 - list_del(&special_alt->list);
8659 - free(special_alt);
8660 - }
8661 -
8662 -out:
8663 - return ret;
8664 -}
8665 -
8666 -static int add_switch_table(struct objtool_file *file, struct symbol *func,
8667 - struct instruction *insn, struct rela *table,
8668 - struct rela *next_table)
8669 -{
8670 - struct rela *rela = table;
8671 - struct instruction *alt_insn;
8672 - struct alternative *alt;
8673 -
8674 - list_for_each_entry_from(rela, &file->rodata->rela->rela_list, list) {
8675 - if (rela == next_table)
8676 - break;
8677 -
8678 - if (rela->sym->sec != insn->sec ||
8679 - rela->addend <= func->offset ||
8680 - rela->addend >= func->offset + func->len)
8681 - break;
8682 -
8683 - alt_insn = find_insn(file, insn->sec, rela->addend);
8684 - if (!alt_insn) {
8685 - WARN("%s: can't find instruction at %s+0x%x",
8686 - file->rodata->rela->name, insn->sec->name,
8687 - rela->addend);
8688 - return -1;
8689 - }
8690 -
8691 - alt = malloc(sizeof(*alt));
8692 - if (!alt) {
8693 - WARN("malloc failed");
8694 - return -1;
8695 - }
8696 -
8697 - alt->insn = alt_insn;
8698 - list_add_tail(&alt->list, &insn->alts);
8699 - }
8700 -
8701 - return 0;
8702 -}
8703 -
8704 -/*
8705 - * find_switch_table() - Given a dynamic jump, find the switch jump table in
8706 - * .rodata associated with it.
8707 - *
8708 - * There are 3 basic patterns:
8709 - *
8710 - * 1. jmpq *[rodata addr](,%reg,8)
8711 - *
8712 - * This is the most common case by far. It jumps to an address in a simple
8713 - * jump table which is stored in .rodata.
8714 - *
8715 - * 2. jmpq *[rodata addr](%rip)
8716 - *
8717 - * This is caused by a rare GCC quirk, currently only seen in three driver
8718 - * functions in the kernel, only with certain obscure non-distro configs.
8719 - *
8720 - * As part of an optimization, GCC makes a copy of an existing switch jump
8721 - * table, modifies it, and then hard-codes the jump (albeit with an indirect
8722 - * jump) to use a single entry in the table. The rest of the jump table and
8723 - * some of its jump targets remain as dead code.
8724 - *
8725 - * In such a case we can just crudely ignore all unreachable instruction
8726 - * warnings for the entire object file. Ideally we would just ignore them
8727 - * for the function, but that would require redesigning the code quite a
8728 - * bit. And honestly that's just not worth doing: unreachable instruction
8729 - * warnings are of questionable value anyway, and this is such a rare issue.
8730 - *
8731 - * 3. mov [rodata addr],%reg1
8732 - * ... some instructions ...
8733 - * jmpq *(%reg1,%reg2,8)
8734 - *
8735 - * This is a fairly uncommon pattern which is new for GCC 6. As of this
8736 - * writing, there are 11 occurrences of it in the allmodconfig kernel.
8737 - *
8738 - * TODO: Once we have DWARF CFI and smarter instruction decoding logic,
8739 - * ensure the same register is used in the mov and jump instructions.
8740 - */
8741 -static struct rela *find_switch_table(struct objtool_file *file,
8742 - struct symbol *func,
8743 - struct instruction *insn)
8744 -{
8745 - struct rela *text_rela, *rodata_rela;
8746 - struct instruction *orig_insn = insn;
8747 -
8748 - text_rela = find_rela_by_dest_range(insn->sec, insn->offset, insn->len);
8749 - if (text_rela && text_rela->sym == file->rodata->sym) {
8750 - /* case 1 */
8751 - rodata_rela = find_rela_by_dest(file->rodata,
8752 - text_rela->addend);
8753 - if (rodata_rela)
8754 - return rodata_rela;
8755 -
8756 - /* case 2 */
8757 - rodata_rela = find_rela_by_dest(file->rodata,
8758 - text_rela->addend + 4);
8759 - if (!rodata_rela)
8760 - return NULL;
8761 - file->ignore_unreachables = true;
8762 - return rodata_rela;
8763 - }
8764 -
8765 - /* case 3 */
8766 - func_for_each_insn_continue_reverse(file, func, insn) {
8767 - if (insn->type == INSN_JUMP_DYNAMIC)
8768 - break;
8769 -
8770 - /* allow small jumps within the range */
8771 - if (insn->type == INSN_JUMP_UNCONDITIONAL &&
8772 - insn->jump_dest &&
8773 - (insn->jump_dest->offset <= insn->offset ||
8774 - insn->jump_dest->offset > orig_insn->offset))
8775 - break;
8776 -
8777 - /* look for a relocation which references .rodata */
8778 - text_rela = find_rela_by_dest_range(insn->sec, insn->offset,
8779 - insn->len);
8780 - if (!text_rela || text_rela->sym != file->rodata->sym)
8781 - continue;
8782 -
8783 - /*
8784 - * Make sure the .rodata address isn't associated with a
8785 - * symbol. gcc jump tables are anonymous data.
8786 - */
8787 - if (find_symbol_containing(file->rodata, text_rela->addend))
8788 - continue;
8789 -
8790 - return find_rela_by_dest(file->rodata, text_rela->addend);
8791 - }
8792 -
8793 - return NULL;
8794 -}
8795 -
8796 -static int add_func_switch_tables(struct objtool_file *file,
8797 - struct symbol *func)
8798 -{
8799 - struct instruction *insn, *prev_jump = NULL;
8800 - struct rela *rela, *prev_rela = NULL;
8801 - int ret;
8802 -
8803 - func_for_each_insn(file, func, insn) {
8804 - if (insn->type != INSN_JUMP_DYNAMIC)
8805 - continue;
8806 -
8807 - rela = find_switch_table(file, func, insn);
8808 - if (!rela)
8809 - continue;
8810 -
8811 - /*
8812 - * We found a switch table, but we don't know yet how big it
8813 - * is. Don't add it until we reach the end of the function or
8814 - * the beginning of another switch table in the same function.
8815 - */
8816 - if (prev_jump) {
8817 - ret = add_switch_table(file, func, prev_jump, prev_rela,
8818 - rela);
8819 - if (ret)
8820 - return ret;
8821 - }
8822 -
8823 - prev_jump = insn;
8824 - prev_rela = rela;
8825 - }
8826 -
8827 - if (prev_jump) {
8828 - ret = add_switch_table(file, func, prev_jump, prev_rela, NULL);
8829 - if (ret)
8830 - return ret;
8831 - }
8832 -
8833 - return 0;
8834 -}
8835 -
8836 -/*
8837 - * For some switch statements, gcc generates a jump table in the .rodata
8838 - * section which contains a list of addresses within the function to jump to.
8839 - * This finds these jump tables and adds them to the insn->alts lists.
8840 - */
8841 -static int add_switch_table_alts(struct objtool_file *file)
8842 -{
8843 - struct section *sec;
8844 - struct symbol *func;
8845 - int ret;
8846 -
8847 - if (!file->rodata || !file->rodata->rela)
8848 - return 0;
8849 -
8850 - list_for_each_entry(sec, &file->elf->sections, list) {
8851 - list_for_each_entry(func, &sec->symbol_list, list) {
8852 - if (func->type != STT_FUNC)
8853 - continue;
8854 -
8855 - ret = add_func_switch_tables(file, func);
8856 - if (ret)
8857 - return ret;
8858 - }
8859 - }
8860 -
8861 - return 0;
8862 -}
8863 -
8864 -static int decode_sections(struct objtool_file *file)
8865 -{
8866 - int ret;
8867 -
8868 - ret = decode_instructions(file);
8869 - if (ret)
8870 - return ret;
8871 -
8872 - add_ignores(file);
8873 -
8874 - ret = add_nospec_ignores(file);
8875 - if (ret)
8876 - return ret;
8877 -
8878 - ret = add_jump_destinations(file);
8879 - if (ret)
8880 - return ret;
8881 -
8882 - ret = add_call_destinations(file);
8883 - if (ret)
8884 - return ret;
8885 -
8886 - ret = add_special_section_alts(file);
8887 - if (ret)
8888 - return ret;
8889 -
8890 - ret = add_switch_table_alts(file);
8891 - if (ret)
8892 - return ret;
8893 -
8894 - return 0;
8895 -}
8896 -
8897 -static bool is_fentry_call(struct instruction *insn)
8898 -{
8899 - if (insn->type == INSN_CALL &&
8900 - insn->call_dest->type == STT_NOTYPE &&
8901 - !strcmp(insn->call_dest->name, "__fentry__"))
8902 - return true;
8903 -
8904 - return false;
8905 -}
8906 -
8907 -static bool has_modified_stack_frame(struct instruction *insn)
8908 -{
8909 - return (insn->state & STATE_FP_SAVED) ||
8910 - (insn->state & STATE_FP_SETUP);
8911 -}
8912 -
8913 -static bool has_valid_stack_frame(struct instruction *insn)
8914 -{
8915 - return (insn->state & STATE_FP_SAVED) &&
8916 - (insn->state & STATE_FP_SETUP);
8917 -}
8918 -
8919 -static unsigned int frame_state(unsigned long state)
8920 -{
8921 - return (state & (STATE_FP_SAVED | STATE_FP_SETUP));
8922 -}
8923 -
8924 -/*
8925 - * Follow the branch starting at the given instruction, and recursively follow
8926 - * any other branches (jumps). Meanwhile, track the frame pointer state at
8927 - * each instruction and validate all the rules described in
8928 - * tools/objtool/Documentation/stack-validation.txt.
8929 - */
8930 -static int validate_branch(struct objtool_file *file,
8931 - struct instruction *first, unsigned char first_state)
8932 -{
8933 - struct alternative *alt;
8934 - struct instruction *insn;
8935 - struct section *sec;
8936 - struct symbol *func = NULL;
8937 - unsigned char state;
8938 - int ret;
8939 -
8940 - insn = first;
8941 - sec = insn->sec;
8942 - state = first_state;
8943 -
8944 - if (insn->alt_group && list_empty(&insn->alts)) {
8945 - WARN_FUNC("don't know how to handle branch to middle of alternative instruction group",
8946 - sec, insn->offset);
8947 - return 1;
8948 - }
8949 -
8950 - while (1) {
8951 - if (file->c_file && insn->func) {
8952 - if (func && func != insn->func) {
8953 - WARN("%s() falls through to next function %s()",
8954 - func->name, insn->func->name);
8955 - return 1;
8956 - }
8957 -
8958 - func = insn->func;
8959 - }
8960 -
8961 - if (insn->visited) {
8962 - if (frame_state(insn->state) != frame_state(state)) {
8963 - WARN_FUNC("frame pointer state mismatch",
8964 - sec, insn->offset);
8965 - return 1;
8966 - }
8967 -
8968 - return 0;
8969 - }
8970 -
8971 - insn->visited = true;
8972 - insn->state = state;
8973 -
8974 - list_for_each_entry(alt, &insn->alts, list) {
8975 - ret = validate_branch(file, alt->insn, state);
8976 - if (ret)
8977 - return 1;
8978 - }
8979 -
8980 - switch (insn->type) {
8981 -
8982 - case INSN_FP_SAVE:
8983 - if (!nofp) {
8984 - if (state & STATE_FP_SAVED) {
8985 - WARN_FUNC("duplicate frame pointer save",
8986 - sec, insn->offset);
8987 - return 1;
8988 - }
8989 - state |= STATE_FP_SAVED;
8990 - }
8991 - break;
8992 -
8993 - case INSN_FP_SETUP:
8994 - if (!nofp) {
8995 - if (state & STATE_FP_SETUP) {
8996 - WARN_FUNC("duplicate frame pointer setup",
8997 - sec, insn->offset);
8998 - return 1;
8999 - }
9000 - state |= STATE_FP_SETUP;
9001 - }
9002 - break;
9003 -
9004 - case INSN_FP_RESTORE:
9005 - if (!nofp) {
9006 - if (has_valid_stack_frame(insn))
9007 - state &= ~STATE_FP_SETUP;
9008 -
9009 - state &= ~STATE_FP_SAVED;
9010 - }
9011 - break;
9012 -
9013 - case INSN_RETURN:
9014 - if (!nofp && has_modified_stack_frame(insn)) {
9015 - WARN_FUNC("return without frame pointer restore",
9016 - sec, insn->offset);
9017 - return 1;
9018 - }
9019 - return 0;
9020 -
9021 - case INSN_CALL:
9022 - if (is_fentry_call(insn)) {
9023 - state |= STATE_FENTRY;
9024 - break;
9025 - }
9026 -
9027 - ret = dead_end_function(file, insn->call_dest);
9028 - if (ret == 1)
9029 - return 0;
9030 - if (ret == -1)
9031 - return 1;
9032 -
9033 - /* fallthrough */
9034 - case INSN_CALL_DYNAMIC:
9035 - if (!nofp && !has_valid_stack_frame(insn)) {
9036 - WARN_FUNC("call without frame pointer save/setup",
9037 - sec, insn->offset);
9038 - return 1;
9039 - }
9040 - break;
9041 -
9042 - case INSN_JUMP_CONDITIONAL:
9043 - case INSN_JUMP_UNCONDITIONAL:
9044 - if (insn->jump_dest) {
9045 - ret = validate_branch(file, insn->jump_dest,
9046 - state);
9047 - if (ret)
9048 - return 1;
9049 - } else if (has_modified_stack_frame(insn)) {
9050 - WARN_FUNC("sibling call from callable instruction with changed frame pointer",
9051 - sec, insn->offset);
9052 - return 1;
9053 - } /* else it's a sibling call */
9054 -
9055 - if (insn->type == INSN_JUMP_UNCONDITIONAL)
9056 - return 0;
9057 -
9058 - break;
9059 -
9060 - case INSN_JUMP_DYNAMIC:
9061 - if (list_empty(&insn->alts) &&
9062 - has_modified_stack_frame(insn)) {
9063 - WARN_FUNC("sibling call from callable instruction with changed frame pointer",
9064 - sec, insn->offset);
9065 - return 1;
9066 - }
9067 -
9068 - return 0;
9069 -
9070 - case INSN_BUG:
9071 - return 0;
9072 -
9073 - default:
9074 - break;
9075 - }
9076 -
9077 - insn = next_insn_same_sec(file, insn);
9078 - if (!insn) {
9079 - WARN("%s: unexpected end of section", sec->name);
9080 - return 1;
9081 - }
9082 - }
9083 -
9084 - return 0;
9085 -}
9086 -
9087 -static bool is_kasan_insn(struct instruction *insn)
9088 -{
9089 - return (insn->type == INSN_CALL &&
9090 - !strcmp(insn->call_dest->name, "__asan_handle_no_return"));
9091 -}
9092 -
9093 -static bool is_ubsan_insn(struct instruction *insn)
9094 -{
9095 - return (insn->type == INSN_CALL &&
9096 - !strcmp(insn->call_dest->name,
9097 - "__ubsan_handle_builtin_unreachable"));
9098 -}
9099 -
9100 -static bool ignore_unreachable_insn(struct symbol *func,
9101 - struct instruction *insn)
9102 -{
9103 - int i;
9104 -
9105 - if (insn->type == INSN_NOP)
9106 - return true;
9107 -
9108 - /*
9109 - * Check if this (or a subsequent) instruction is related to
9110 - * CONFIG_UBSAN or CONFIG_KASAN.
9111 - *
9112 - * End the search at 5 instructions to avoid going into the weeds.
9113 - */
9114 - for (i = 0; i < 5; i++) {
9115 -
9116 - if (is_kasan_insn(insn) || is_ubsan_insn(insn))
9117 - return true;
9118 -
9119 - if (insn->type == INSN_JUMP_UNCONDITIONAL && insn->jump_dest) {
9120 - insn = insn->jump_dest;
9121 - continue;
9122 - }
9123 -
9124 - if (insn->offset + insn->len >= func->offset + func->len)
9125 - break;
9126 - insn = list_next_entry(insn, list);
9127 - }
9128 -
9129 - return false;
9130 -}
9131 -
9132 -static int validate_functions(struct objtool_file *file)
9133 -{
9134 - struct section *sec;
9135 - struct symbol *func;
9136 - struct instruction *insn;
9137 - int ret, warnings = 0;
9138 -
9139 - list_for_each_entry(sec, &file->elf->sections, list) {
9140 - list_for_each_entry(func, &sec->symbol_list, list) {
9141 - if (func->type != STT_FUNC)
9142 - continue;
9143 -
9144 - insn = find_insn(file, sec, func->offset);
9145 - if (!insn)
9146 - continue;
9147 -
9148 - ret = validate_branch(file, insn, 0);
9149 - warnings += ret;
9150 - }
9151 - }
9152 -
9153 - list_for_each_entry(sec, &file->elf->sections, list) {
9154 - list_for_each_entry(func, &sec->symbol_list, list) {
9155 - if (func->type != STT_FUNC)
9156 - continue;
9157 -
9158 - func_for_each_insn(file, func, insn) {
9159 - if (insn->visited)
9160 - continue;
9161 -
9162 - insn->visited = true;
9163 -
9164 - if (file->ignore_unreachables || warnings ||
9165 - ignore_unreachable_insn(func, insn))
9166 - continue;
9167 -
9168 - /*
9169 - * gcov produces a lot of unreachable
9170 - * instructions. If we get an unreachable
9171 - * warning and the file has gcov enabled, just
9172 - * ignore it, and all other such warnings for
9173 - * the file.
9174 - */
9175 - if (!file->ignore_unreachables &&
9176 - gcov_enabled(file)) {
9177 - file->ignore_unreachables = true;
9178 - continue;
9179 - }
9180 -
9181 - WARN_FUNC("function has unreachable instruction", insn->sec, insn->offset);
9182 - warnings++;
9183 - }
9184 - }
9185 - }
9186 -
9187 - return warnings;
9188 -}
9189 -
9190 -static int validate_uncallable_instructions(struct objtool_file *file)
9191 -{
9192 - struct instruction *insn;
9193 - int warnings = 0;
9194 -
9195 - for_each_insn(file, insn) {
9196 - if (!insn->visited && insn->type == INSN_RETURN) {
9197 -
9198 - /*
9199 - * Don't warn about call instructions in unvisited
9200 - * retpoline alternatives.
9201 - */
9202 - if (!strcmp(insn->sec->name, ".altinstr_replacement"))
9203 - continue;
9204 -
9205 - WARN_FUNC("return instruction outside of a callable function",
9206 - insn->sec, insn->offset);
9207 - warnings++;
9208 - }
9209 - }
9210 -
9211 - return warnings;
9212 -}
9213 -
9214 -static void cleanup(struct objtool_file *file)
9215 -{
9216 - struct instruction *insn, *tmpinsn;
9217 - struct alternative *alt, *tmpalt;
9218 -
9219 - list_for_each_entry_safe(insn, tmpinsn, &file->insn_list, list) {
9220 - list_for_each_entry_safe(alt, tmpalt, &insn->alts, list) {
9221 - list_del(&alt->list);
9222 - free(alt);
9223 - }
9224 - list_del(&insn->list);
9225 - hash_del(&insn->hash);
9226 - free(insn);
9227 - }
9228 - elf_close(file->elf);
9229 -}
9230 -
9231 -const char * const check_usage[] = {
9232 +static const char * const check_usage[] = {
9233 "objtool check [<options>] file.o",
9234 NULL,
9235 };
9236
9237 +const struct option check_options[] = {
9238 + OPT_BOOLEAN('f', "no-fp", &no_fp, "Skip frame pointer validation"),
9239 + OPT_BOOLEAN('u', "no-unreachable", &no_unreachable, "Skip 'unreachable instruction' warnings"),
9240 + OPT_BOOLEAN('r', "retpoline", &retpoline, "Validate retpoline assumptions"),
9241 + OPT_BOOLEAN('m', "module", &module, "Indicates the object will be part of a kernel module"),
9242 + OPT_END(),
9243 +};
9244 +
9245 int cmd_check(int argc, const char **argv)
9246 {
9247 - struct objtool_file file;
9248 - int ret, warnings = 0;
9249 -
9250 - const struct option options[] = {
9251 - OPT_BOOLEAN('f', "no-fp", &nofp, "Skip frame pointer validation"),
9252 - OPT_END(),
9253 - };
9254 + const char *objname;
9255
9256 - argc = parse_options(argc, argv, options, check_usage, 0);
9257 + argc = parse_options(argc, argv, check_options, check_usage, 0);
9258
9259 if (argc != 1)
9260 - usage_with_options(check_usage, options);
9261 + usage_with_options(check_usage, check_options);
9262
9263 objname = argv[0];
9264
9265 - file.elf = elf_open(objname);
9266 - if (!file.elf) {
9267 - fprintf(stderr, "error reading elf file %s\n", objname);
9268 - return 1;
9269 - }
9270 -
9271 - INIT_LIST_HEAD(&file.insn_list);
9272 - hash_init(file.insn_hash);
9273 - file.whitelist = find_section_by_name(file.elf, ".discard.func_stack_frame_non_standard");
9274 - file.rodata = find_section_by_name(file.elf, ".rodata");
9275 - file.ignore_unreachables = false;
9276 - file.c_file = find_section_by_name(file.elf, ".comment");
9277 -
9278 - ret = decode_sections(&file);
9279 - if (ret < 0)
9280 - goto out;
9281 - warnings += ret;
9282 -
9283 - ret = validate_functions(&file);
9284 - if (ret < 0)
9285 - goto out;
9286 - warnings += ret;
9287 -
9288 - ret = validate_uncallable_instructions(&file);
9289 - if (ret < 0)
9290 - goto out;
9291 - warnings += ret;
9292 -
9293 -out:
9294 - cleanup(&file);
9295 -
9296 - /* ignore warnings for now until we get all the code cleaned up */
9297 - if (ret || warnings)
9298 - return 0;
9299 - return 0;
9300 + return check(objname, false);
9301 }
9302 diff --git a/tools/objtool/builtin-orc.c b/tools/objtool/builtin-orc.c
9303 new file mode 100644
9304 index 000000000000..77ea2b97117d
9305 --- /dev/null
9306 +++ b/tools/objtool/builtin-orc.c
9307 @@ -0,0 +1,68 @@
9308 +/*
9309 + * Copyright (C) 2017 Josh Poimboeuf <jpoimboe@redhat.com>
9310 + *
9311 + * This program is free software; you can redistribute it and/or
9312 + * modify it under the terms of the GNU General Public License
9313 + * as published by the Free Software Foundation; either version 2
9314 + * of the License, or (at your option) any later version.
9315 + *
9316 + * This program is distributed in the hope that it will be useful,
9317 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
9318 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9319 + * GNU General Public License for more details.
9320 + *
9321 + * You should have received a copy of the GNU General Public License
9322 + * along with this program; if not, see <http://www.gnu.org/licenses/>.
9323 + */
9324 +
9325 +/*
9326 + * objtool orc:
9327 + *
9328 + * This command analyzes a .o file and adds .orc_unwind and .orc_unwind_ip
9329 + * sections to it, which is used by the in-kernel ORC unwinder.
9330 + *
9331 + * This command is a superset of "objtool check".
9332 + */
9333 +
9334 +#include <string.h>
9335 +#include "builtin.h"
9336 +#include "check.h"
9337 +
9338 +
9339 +static const char *orc_usage[] = {
9340 + "objtool orc generate [<options>] file.o",
9341 + "objtool orc dump file.o",
9342 + NULL,
9343 +};
9344 +
9345 +int cmd_orc(int argc, const char **argv)
9346 +{
9347 + const char *objname;
9348 +
9349 + argc--; argv++;
9350 + if (argc <= 0)
9351 + usage_with_options(orc_usage, check_options);
9352 +
9353 + if (!strncmp(argv[0], "gen", 3)) {
9354 + argc = parse_options(argc, argv, check_options, orc_usage, 0);
9355 + if (argc != 1)
9356 + usage_with_options(orc_usage, check_options);
9357 +
9358 + objname = argv[0];
9359 +
9360 + return check(objname, true);
9361 + }
9362 +
9363 + if (!strcmp(argv[0], "dump")) {
9364 + if (argc != 2)
9365 + usage_with_options(orc_usage, check_options);
9366 +
9367 + objname = argv[1];
9368 +
9369 + return orc_dump(objname);
9370 + }
9371 +
9372 + usage_with_options(orc_usage, check_options);
9373 +
9374 + return 0;
9375 +}
9376 diff --git a/tools/objtool/builtin.h b/tools/objtool/builtin.h
9377 index 34d2ba78a616..28ff40e19a14 100644
9378 --- a/tools/objtool/builtin.h
9379 +++ b/tools/objtool/builtin.h
9380 @@ -17,6 +17,12 @@
9381 #ifndef _BUILTIN_H
9382 #define _BUILTIN_H
9383
9384 +#include <subcmd/parse-options.h>
9385 +
9386 +extern const struct option check_options[];
9387 +extern bool no_fp, no_unreachable, retpoline, module;
9388 +
9389 extern int cmd_check(int argc, const char **argv);
9390 +extern int cmd_orc(int argc, const char **argv);
9391
9392 #endif /* _BUILTIN_H */
9393 diff --git a/tools/objtool/cfi.h b/tools/objtool/cfi.h
9394 new file mode 100644
9395 index 000000000000..2fe883c665c7
9396 --- /dev/null
9397 +++ b/tools/objtool/cfi.h
9398 @@ -0,0 +1,55 @@
9399 +/*
9400 + * Copyright (C) 2015-2017 Josh Poimboeuf <jpoimboe@redhat.com>
9401 + *
9402 + * This program is free software; you can redistribute it and/or
9403 + * modify it under the terms of the GNU General Public License
9404 + * as published by the Free Software Foundation; either version 2
9405 + * of the License, or (at your option) any later version.
9406 + *
9407 + * This program is distributed in the hope that it will be useful,
9408 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
9409 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9410 + * GNU General Public License for more details.
9411 + *
9412 + * You should have received a copy of the GNU General Public License
9413 + * along with this program; if not, see <http://www.gnu.org/licenses/>.
9414 + */
9415 +
9416 +#ifndef _OBJTOOL_CFI_H
9417 +#define _OBJTOOL_CFI_H
9418 +
9419 +#define CFI_UNDEFINED -1
9420 +#define CFI_CFA -2
9421 +#define CFI_SP_INDIRECT -3
9422 +#define CFI_BP_INDIRECT -4
9423 +
9424 +#define CFI_AX 0
9425 +#define CFI_DX 1
9426 +#define CFI_CX 2
9427 +#define CFI_BX 3
9428 +#define CFI_SI 4
9429 +#define CFI_DI 5
9430 +#define CFI_BP 6
9431 +#define CFI_SP 7
9432 +#define CFI_R8 8
9433 +#define CFI_R9 9
9434 +#define CFI_R10 10
9435 +#define CFI_R11 11
9436 +#define CFI_R12 12
9437 +#define CFI_R13 13
9438 +#define CFI_R14 14
9439 +#define CFI_R15 15
9440 +#define CFI_RA 16
9441 +#define CFI_NUM_REGS 17
9442 +
9443 +struct cfi_reg {
9444 + int base;
9445 + int offset;
9446 +};
9447 +
9448 +struct cfi_state {
9449 + struct cfi_reg cfa;
9450 + struct cfi_reg regs[CFI_NUM_REGS];
9451 +};
9452 +
9453 +#endif /* _OBJTOOL_CFI_H */
9454 diff --git a/tools/objtool/check.c b/tools/objtool/check.c
9455 new file mode 100644
9456 index 000000000000..e128d1c71c30
9457 --- /dev/null
9458 +++ b/tools/objtool/check.c
9459 @@ -0,0 +1,2209 @@
9460 +/*
9461 + * Copyright (C) 2015-2017 Josh Poimboeuf <jpoimboe@redhat.com>
9462 + *
9463 + * This program is free software; you can redistribute it and/or
9464 + * modify it under the terms of the GNU General Public License
9465 + * as published by the Free Software Foundation; either version 2
9466 + * of the License, or (at your option) any later version.
9467 + *
9468 + * This program is distributed in the hope that it will be useful,
9469 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
9470 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9471 + * GNU General Public License for more details.
9472 + *
9473 + * You should have received a copy of the GNU General Public License
9474 + * along with this program; if not, see <http://www.gnu.org/licenses/>.
9475 + */
9476 +
9477 +#include <string.h>
9478 +#include <stdlib.h>
9479 +
9480 +#include "builtin.h"
9481 +#include "check.h"
9482 +#include "elf.h"
9483 +#include "special.h"
9484 +#include "arch.h"
9485 +#include "warn.h"
9486 +
9487 +#include <linux/hashtable.h>
9488 +#include <linux/kernel.h>
9489 +
9490 +struct alternative {
9491 + struct list_head list;
9492 + struct instruction *insn;
9493 +};
9494 +
9495 +const char *objname;
9496 +struct cfi_state initial_func_cfi;
9497 +
9498 +struct instruction *find_insn(struct objtool_file *file,
9499 + struct section *sec, unsigned long offset)
9500 +{
9501 + struct instruction *insn;
9502 +
9503 + hash_for_each_possible(file->insn_hash, insn, hash, offset)
9504 + if (insn->sec == sec && insn->offset == offset)
9505 + return insn;
9506 +
9507 + return NULL;
9508 +}
9509 +
9510 +static struct instruction *next_insn_same_sec(struct objtool_file *file,
9511 + struct instruction *insn)
9512 +{
9513 + struct instruction *next = list_next_entry(insn, list);
9514 +
9515 + if (!next || &next->list == &file->insn_list || next->sec != insn->sec)
9516 + return NULL;
9517 +
9518 + return next;
9519 +}
9520 +
9521 +static struct instruction *next_insn_same_func(struct objtool_file *file,
9522 + struct instruction *insn)
9523 +{
9524 + struct instruction *next = list_next_entry(insn, list);
9525 + struct symbol *func = insn->func;
9526 +
9527 + if (!func)
9528 + return NULL;
9529 +
9530 + if (&next->list != &file->insn_list && next->func == func)
9531 + return next;
9532 +
9533 + /* Check if we're already in the subfunction: */
9534 + if (func == func->cfunc)
9535 + return NULL;
9536 +
9537 + /* Move to the subfunction: */
9538 + return find_insn(file, func->cfunc->sec, func->cfunc->offset);
9539 +}
9540 +
9541 +#define func_for_each_insn_all(file, func, insn) \
9542 + for (insn = find_insn(file, func->sec, func->offset); \
9543 + insn; \
9544 + insn = next_insn_same_func(file, insn))
9545 +
9546 +#define func_for_each_insn(file, func, insn) \
9547 + for (insn = find_insn(file, func->sec, func->offset); \
9548 + insn && &insn->list != &file->insn_list && \
9549 + insn->sec == func->sec && \
9550 + insn->offset < func->offset + func->len; \
9551 + insn = list_next_entry(insn, list))
9552 +
9553 +#define func_for_each_insn_continue_reverse(file, func, insn) \
9554 + for (insn = list_prev_entry(insn, list); \
9555 + &insn->list != &file->insn_list && \
9556 + insn->sec == func->sec && insn->offset >= func->offset; \
9557 + insn = list_prev_entry(insn, list))
9558 +
9559 +#define sec_for_each_insn_from(file, insn) \
9560 + for (; insn; insn = next_insn_same_sec(file, insn))
9561 +
9562 +#define sec_for_each_insn_continue(file, insn) \
9563 + for (insn = next_insn_same_sec(file, insn); insn; \
9564 + insn = next_insn_same_sec(file, insn))
9565 +
9566 +/*
9567 + * Check if the function has been manually whitelisted with the
9568 + * STACK_FRAME_NON_STANDARD macro, or if it should be automatically whitelisted
9569 + * due to its use of a context switching instruction.
9570 + */
9571 +static bool ignore_func(struct objtool_file *file, struct symbol *func)
9572 +{
9573 + struct rela *rela;
9574 +
9575 + /* check for STACK_FRAME_NON_STANDARD */
9576 + if (file->whitelist && file->whitelist->rela)
9577 + list_for_each_entry(rela, &file->whitelist->rela->rela_list, list) {
9578 + if (rela->sym->type == STT_SECTION &&
9579 + rela->sym->sec == func->sec &&
9580 + rela->addend == func->offset)
9581 + return true;
9582 + if (rela->sym->type == STT_FUNC && rela->sym == func)
9583 + return true;
9584 + }
9585 +
9586 + return false;
9587 +}
9588 +
9589 +/*
9590 + * This checks to see if the given function is a "noreturn" function.
9591 + *
9592 + * For global functions which are outside the scope of this object file, we
9593 + * have to keep a manual list of them.
9594 + *
9595 + * For local functions, we have to detect them manually by simply looking for
9596 + * the lack of a return instruction.
9597 + *
9598 + * Returns:
9599 + * -1: error
9600 + * 0: no dead end
9601 + * 1: dead end
9602 + */
9603 +static int __dead_end_function(struct objtool_file *file, struct symbol *func,
9604 + int recursion)
9605 +{
9606 + int i;
9607 + struct instruction *insn;
9608 + bool empty = true;
9609 +
9610 + /*
9611 + * Unfortunately these have to be hard coded because the noreturn
9612 + * attribute isn't provided in ELF data.
9613 + */
9614 + static const char * const global_noreturns[] = {
9615 + "__stack_chk_fail",
9616 + "panic",
9617 + "do_exit",
9618 + "do_task_dead",
9619 + "__module_put_and_exit",
9620 + "complete_and_exit",
9621 + "kvm_spurious_fault",
9622 + "__reiserfs_panic",
9623 + "lbug_with_loc",
9624 + "fortify_panic",
9625 + };
9626 +
9627 + if (func->bind == STB_WEAK)
9628 + return 0;
9629 +
9630 + if (func->bind == STB_GLOBAL)
9631 + for (i = 0; i < ARRAY_SIZE(global_noreturns); i++)
9632 + if (!strcmp(func->name, global_noreturns[i]))
9633 + return 1;
9634 +
9635 + if (!func->len)
9636 + return 0;
9637 +
9638 + insn = find_insn(file, func->sec, func->offset);
9639 + if (!insn->func)
9640 + return 0;
9641 +
9642 + func_for_each_insn_all(file, func, insn) {
9643 + empty = false;
9644 +
9645 + if (insn->type == INSN_RETURN)
9646 + return 0;
9647 + }
9648 +
9649 + if (empty)
9650 + return 0;
9651 +
9652 + /*
9653 + * A function can have a sibling call instead of a return. In that
9654 + * case, the function's dead-end status depends on whether the target
9655 + * of the sibling call returns.
9656 + */
9657 + func_for_each_insn_all(file, func, insn) {
9658 + if (insn->type == INSN_JUMP_UNCONDITIONAL) {
9659 + struct instruction *dest = insn->jump_dest;
9660 +
9661 + if (!dest)
9662 + /* sibling call to another file */
9663 + return 0;
9664 +
9665 + if (dest->func && dest->func->pfunc != insn->func->pfunc) {
9666 +
9667 + /* local sibling call */
9668 + if (recursion == 5) {
9669 + /*
9670 + * Infinite recursion: two functions
9671 + * have sibling calls to each other.
9672 + * This is a very rare case. It means
9673 + * they aren't dead ends.
9674 + */
9675 + return 0;
9676 + }
9677 +
9678 + return __dead_end_function(file, dest->func,
9679 + recursion + 1);
9680 + }
9681 + }
9682 +
9683 + if (insn->type == INSN_JUMP_DYNAMIC && list_empty(&insn->alts))
9684 + /* sibling call */
9685 + return 0;
9686 + }
9687 +
9688 + return 1;
9689 +}
9690 +
9691 +static int dead_end_function(struct objtool_file *file, struct symbol *func)
9692 +{
9693 + return __dead_end_function(file, func, 0);
9694 +}
9695 +
9696 +static void clear_insn_state(struct insn_state *state)
9697 +{
9698 + int i;
9699 +
9700 + memset(state, 0, sizeof(*state));
9701 + state->cfa.base = CFI_UNDEFINED;
9702 + for (i = 0; i < CFI_NUM_REGS; i++) {
9703 + state->regs[i].base = CFI_UNDEFINED;
9704 + state->vals[i].base = CFI_UNDEFINED;
9705 + }
9706 + state->drap_reg = CFI_UNDEFINED;
9707 + state->drap_offset = -1;
9708 +}
9709 +
9710 +/*
9711 + * Call the arch-specific instruction decoder for all the instructions and add
9712 + * them to the global instruction list.
9713 + */
9714 +static int decode_instructions(struct objtool_file *file)
9715 +{
9716 + struct section *sec;
9717 + struct symbol *func;
9718 + unsigned long offset;
9719 + struct instruction *insn;
9720 + int ret;
9721 +
9722 + for_each_sec(file, sec) {
9723 +
9724 + if (!(sec->sh.sh_flags & SHF_EXECINSTR))
9725 + continue;
9726 +
9727 + if (strcmp(sec->name, ".altinstr_replacement") &&
9728 + strcmp(sec->name, ".altinstr_aux") &&
9729 + strncmp(sec->name, ".discard.", 9))
9730 + sec->text = true;
9731 +
9732 + for (offset = 0; offset < sec->len; offset += insn->len) {
9733 + insn = malloc(sizeof(*insn));
9734 + if (!insn) {
9735 + WARN("malloc failed");
9736 + return -1;
9737 + }
9738 + memset(insn, 0, sizeof(*insn));
9739 + INIT_LIST_HEAD(&insn->alts);
9740 + clear_insn_state(&insn->state);
9741 +
9742 + insn->sec = sec;
9743 + insn->offset = offset;
9744 +
9745 + ret = arch_decode_instruction(file->elf, sec, offset,
9746 + sec->len - offset,
9747 + &insn->len, &insn->type,
9748 + &insn->immediate,
9749 + &insn->stack_op);
9750 + if (ret)
9751 + goto err;
9752 +
9753 + if (!insn->type || insn->type > INSN_LAST) {
9754 + WARN_FUNC("invalid instruction type %d",
9755 + insn->sec, insn->offset, insn->type);
9756 + ret = -1;
9757 + goto err;
9758 + }
9759 +
9760 + hash_add(file->insn_hash, &insn->hash, insn->offset);
9761 + list_add_tail(&insn->list, &file->insn_list);
9762 + }
9763 +
9764 + list_for_each_entry(func, &sec->symbol_list, list) {
9765 + if (func->type != STT_FUNC)
9766 + continue;
9767 +
9768 + if (!find_insn(file, sec, func->offset)) {
9769 + WARN("%s(): can't find starting instruction",
9770 + func->name);
9771 + return -1;
9772 + }
9773 +
9774 + func_for_each_insn(file, func, insn)
9775 + if (!insn->func)
9776 + insn->func = func;
9777 + }
9778 + }
9779 +
9780 + return 0;
9781 +
9782 +err:
9783 + free(insn);
9784 + return ret;
9785 +}
9786 +
9787 +/*
9788 + * Mark "ud2" instructions and manually annotated dead ends.
9789 + */
9790 +static int add_dead_ends(struct objtool_file *file)
9791 +{
9792 + struct section *sec;
9793 + struct rela *rela;
9794 + struct instruction *insn;
9795 + bool found;
9796 +
9797 + /*
9798 + * By default, "ud2" is a dead end unless otherwise annotated, because
9799 + * GCC 7 inserts it for certain divide-by-zero cases.
9800 + */
9801 + for_each_insn(file, insn)
9802 + if (insn->type == INSN_BUG)
9803 + insn->dead_end = true;
9804 +
9805 + /*
9806 + * Check for manually annotated dead ends.
9807 + */
9808 + sec = find_section_by_name(file->elf, ".rela.discard.unreachable");
9809 + if (!sec)
9810 + goto reachable;
9811 +
9812 + list_for_each_entry(rela, &sec->rela_list, list) {
9813 + if (rela->sym->type != STT_SECTION) {
9814 + WARN("unexpected relocation symbol type in %s", sec->name);
9815 + return -1;
9816 + }
9817 + insn = find_insn(file, rela->sym->sec, rela->addend);
9818 + if (insn)
9819 + insn = list_prev_entry(insn, list);
9820 + else if (rela->addend == rela->sym->sec->len) {
9821 + found = false;
9822 + list_for_each_entry_reverse(insn, &file->insn_list, list) {
9823 + if (insn->sec == rela->sym->sec) {
9824 + found = true;
9825 + break;
9826 + }
9827 + }
9828 +
9829 + if (!found) {
9830 + WARN("can't find unreachable insn at %s+0x%x",
9831 + rela->sym->sec->name, rela->addend);
9832 + return -1;
9833 + }
9834 + } else {
9835 + WARN("can't find unreachable insn at %s+0x%x",
9836 + rela->sym->sec->name, rela->addend);
9837 + return -1;
9838 + }
9839 +
9840 + insn->dead_end = true;
9841 + }
9842 +
9843 +reachable:
9844 + /*
9845 + * These manually annotated reachable checks are needed for GCC 4.4,
9846 + * where the Linux unreachable() macro isn't supported. In that case
9847 + * GCC doesn't know the "ud2" is fatal, so it generates code as if it's
9848 + * not a dead end.
9849 + */
9850 + sec = find_section_by_name(file->elf, ".rela.discard.reachable");
9851 + if (!sec)
9852 + return 0;
9853 +
9854 + list_for_each_entry(rela, &sec->rela_list, list) {
9855 + if (rela->sym->type != STT_SECTION) {
9856 + WARN("unexpected relocation symbol type in %s", sec->name);
9857 + return -1;
9858 + }
9859 + insn = find_insn(file, rela->sym->sec, rela->addend);
9860 + if (insn)
9861 + insn = list_prev_entry(insn, list);
9862 + else if (rela->addend == rela->sym->sec->len) {
9863 + found = false;
9864 + list_for_each_entry_reverse(insn, &file->insn_list, list) {
9865 + if (insn->sec == rela->sym->sec) {
9866 + found = true;
9867 + break;
9868 + }
9869 + }
9870 +
9871 + if (!found) {
9872 + WARN("can't find reachable insn at %s+0x%x",
9873 + rela->sym->sec->name, rela->addend);
9874 + return -1;
9875 + }
9876 + } else {
9877 + WARN("can't find reachable insn at %s+0x%x",
9878 + rela->sym->sec->name, rela->addend);
9879 + return -1;
9880 + }
9881 +
9882 + insn->dead_end = false;
9883 + }
9884 +
9885 + return 0;
9886 +}
9887 +
9888 +/*
9889 + * Warnings shouldn't be reported for ignored functions.
9890 + */
9891 +static void add_ignores(struct objtool_file *file)
9892 +{
9893 + struct instruction *insn;
9894 + struct section *sec;
9895 + struct symbol *func;
9896 +
9897 + for_each_sec(file, sec) {
9898 + list_for_each_entry(func, &sec->symbol_list, list) {
9899 + if (func->type != STT_FUNC)
9900 + continue;
9901 +
9902 + if (!ignore_func(file, func))
9903 + continue;
9904 +
9905 + func_for_each_insn_all(file, func, insn)
9906 + insn->ignore = true;
9907 + }
9908 + }
9909 +}
9910 +
9911 +/*
9912 + * FIXME: For now, just ignore any alternatives which add retpolines. This is
9913 + * a temporary hack, as it doesn't allow ORC to unwind from inside a retpoline.
9914 + * But it at least allows objtool to understand the control flow *around* the
9915 + * retpoline.
9916 + */
9917 +static int add_nospec_ignores(struct objtool_file *file)
9918 +{
9919 + struct section *sec;
9920 + struct rela *rela;
9921 + struct instruction *insn;
9922 +
9923 + sec = find_section_by_name(file->elf, ".rela.discard.nospec");
9924 + if (!sec)
9925 + return 0;
9926 +
9927 + list_for_each_entry(rela, &sec->rela_list, list) {
9928 + if (rela->sym->type != STT_SECTION) {
9929 + WARN("unexpected relocation symbol type in %s", sec->name);
9930 + return -1;
9931 + }
9932 +
9933 + insn = find_insn(file, rela->sym->sec, rela->addend);
9934 + if (!insn) {
9935 + WARN("bad .discard.nospec entry");
9936 + return -1;
9937 + }
9938 +
9939 + insn->ignore_alts = true;
9940 + }
9941 +
9942 + return 0;
9943 +}
9944 +
9945 +/*
9946 + * Find the destination instructions for all jumps.
9947 + */
9948 +static int add_jump_destinations(struct objtool_file *file)
9949 +{
9950 + struct instruction *insn;
9951 + struct rela *rela;
9952 + struct section *dest_sec;
9953 + unsigned long dest_off;
9954 +
9955 + for_each_insn(file, insn) {
9956 + if (insn->type != INSN_JUMP_CONDITIONAL &&
9957 + insn->type != INSN_JUMP_UNCONDITIONAL)
9958 + continue;
9959 +
9960 + if (insn->ignore)
9961 + continue;
9962 +
9963 + rela = find_rela_by_dest_range(insn->sec, insn->offset,
9964 + insn->len);
9965 + if (!rela) {
9966 + dest_sec = insn->sec;
9967 + dest_off = insn->offset + insn->len + insn->immediate;
9968 + } else if (rela->sym->type == STT_SECTION) {
9969 + dest_sec = rela->sym->sec;
9970 + dest_off = rela->addend + 4;
9971 + } else if (rela->sym->sec->idx) {
9972 + dest_sec = rela->sym->sec;
9973 + dest_off = rela->sym->sym.st_value + rela->addend + 4;
9974 + } else if (strstr(rela->sym->name, "_indirect_thunk_")) {
9975 + /*
9976 + * Retpoline jumps are really dynamic jumps in
9977 + * disguise, so convert them accordingly.
9978 + */
9979 + insn->type = INSN_JUMP_DYNAMIC;
9980 + insn->retpoline_safe = true;
9981 + continue;
9982 + } else {
9983 + /* sibling call */
9984 + insn->jump_dest = 0;
9985 + continue;
9986 + }
9987 +
9988 + insn->jump_dest = find_insn(file, dest_sec, dest_off);
9989 + if (!insn->jump_dest) {
9990 +
9991 + /*
9992 + * This is a special case where an alt instruction
9993 + * jumps past the end of the section. These are
9994 + * handled later in handle_group_alt().
9995 + */
9996 + if (!strcmp(insn->sec->name, ".altinstr_replacement"))
9997 + continue;
9998 +
9999 + WARN_FUNC("can't find jump dest instruction at %s+0x%lx",
10000 + insn->sec, insn->offset, dest_sec->name,
10001 + dest_off);
10002 + return -1;
10003 + }
10004 + }
10005 +
10006 + return 0;
10007 +}
10008 +
10009 +/*
10010 + * Find the destination instructions for all calls.
10011 + */
10012 +static int add_call_destinations(struct objtool_file *file)
10013 +{
10014 + struct instruction *insn;
10015 + unsigned long dest_off;
10016 + struct rela *rela;
10017 +
10018 + for_each_insn(file, insn) {
10019 + if (insn->type != INSN_CALL)
10020 + continue;
10021 +
10022 + rela = find_rela_by_dest_range(insn->sec, insn->offset,
10023 + insn->len);
10024 + if (!rela) {
10025 + dest_off = insn->offset + insn->len + insn->immediate;
10026 + insn->call_dest = find_symbol_by_offset(insn->sec,
10027 + dest_off);
10028 +
10029 + if (!insn->call_dest && !insn->ignore) {
10030 + WARN_FUNC("unsupported intra-function call",
10031 + insn->sec, insn->offset);
10032 + if (retpoline)
10033 + WARN("If this is a retpoline, please patch it in with alternatives and annotate it with ANNOTATE_NOSPEC_ALTERNATIVE.");
10034 + return -1;
10035 + }
10036 +
10037 + } else if (rela->sym->type == STT_SECTION) {
10038 + insn->call_dest = find_symbol_by_offset(rela->sym->sec,
10039 + rela->addend+4);
10040 + if (!insn->call_dest ||
10041 + insn->call_dest->type != STT_FUNC) {
10042 + WARN_FUNC("can't find call dest symbol at %s+0x%x",
10043 + insn->sec, insn->offset,
10044 + rela->sym->sec->name,
10045 + rela->addend + 4);
10046 + return -1;
10047 + }
10048 + } else
10049 + insn->call_dest = rela->sym;
10050 + }
10051 +
10052 + return 0;
10053 +}
10054 +
10055 +/*
10056 + * The .alternatives section requires some extra special care, over and above
10057 + * what other special sections require:
10058 + *
10059 + * 1. Because alternatives are patched in-place, we need to insert a fake jump
10060 + * instruction at the end so that validate_branch() skips all the original
10061 + * replaced instructions when validating the new instruction path.
10062 + *
10063 + * 2. An added wrinkle is that the new instruction length might be zero. In
10064 + * that case the old instructions are replaced with noops. We simulate that
10065 + * by creating a fake jump as the only new instruction.
10066 + *
10067 + * 3. In some cases, the alternative section includes an instruction which
10068 + * conditionally jumps to the _end_ of the entry. We have to modify these
10069 + * jumps' destinations to point back to .text rather than the end of the
10070 + * entry in .altinstr_replacement.
10071 + *
10072 + * 4. It has been requested that we don't validate the !POPCNT feature path
10073 + * which is a "very very small percentage of machines".
10074 + */
10075 +static int handle_group_alt(struct objtool_file *file,
10076 + struct special_alt *special_alt,
10077 + struct instruction *orig_insn,
10078 + struct instruction **new_insn)
10079 +{
10080 + struct instruction *last_orig_insn, *last_new_insn, *insn, *fake_jump = NULL;
10081 + unsigned long dest_off;
10082 +
10083 + last_orig_insn = NULL;
10084 + insn = orig_insn;
10085 + sec_for_each_insn_from(file, insn) {
10086 + if (insn->offset >= special_alt->orig_off + special_alt->orig_len)
10087 + break;
10088 +
10089 + if (special_alt->skip_orig)
10090 + insn->type = INSN_NOP;
10091 +
10092 + insn->alt_group = true;
10093 + last_orig_insn = insn;
10094 + }
10095 +
10096 + if (next_insn_same_sec(file, last_orig_insn)) {
10097 + fake_jump = malloc(sizeof(*fake_jump));
10098 + if (!fake_jump) {
10099 + WARN("malloc failed");
10100 + return -1;
10101 + }
10102 + memset(fake_jump, 0, sizeof(*fake_jump));
10103 + INIT_LIST_HEAD(&fake_jump->alts);
10104 + clear_insn_state(&fake_jump->state);
10105 +
10106 + fake_jump->sec = special_alt->new_sec;
10107 + fake_jump->offset = -1;
10108 + fake_jump->type = INSN_JUMP_UNCONDITIONAL;
10109 + fake_jump->jump_dest = list_next_entry(last_orig_insn, list);
10110 + fake_jump->ignore = true;
10111 + }
10112 +
10113 + if (!special_alt->new_len) {
10114 + if (!fake_jump) {
10115 + WARN("%s: empty alternative at end of section",
10116 + special_alt->orig_sec->name);
10117 + return -1;
10118 + }
10119 +
10120 + *new_insn = fake_jump;
10121 + return 0;
10122 + }
10123 +
10124 + last_new_insn = NULL;
10125 + insn = *new_insn;
10126 + sec_for_each_insn_from(file, insn) {
10127 + if (insn->offset >= special_alt->new_off + special_alt->new_len)
10128 + break;
10129 +
10130 + last_new_insn = insn;
10131 +
10132 + insn->ignore = orig_insn->ignore_alts;
10133 +
10134 + if (insn->type != INSN_JUMP_CONDITIONAL &&
10135 + insn->type != INSN_JUMP_UNCONDITIONAL)
10136 + continue;
10137 +
10138 + if (!insn->immediate)
10139 + continue;
10140 +
10141 + dest_off = insn->offset + insn->len + insn->immediate;
10142 + if (dest_off == special_alt->new_off + special_alt->new_len) {
10143 + if (!fake_jump) {
10144 + WARN("%s: alternative jump to end of section",
10145 + special_alt->orig_sec->name);
10146 + return -1;
10147 + }
10148 + insn->jump_dest = fake_jump;
10149 + }
10150 +
10151 + if (!insn->jump_dest) {
10152 + WARN_FUNC("can't find alternative jump destination",
10153 + insn->sec, insn->offset);
10154 + return -1;
10155 + }
10156 + }
10157 +
10158 + if (!last_new_insn) {
10159 + WARN_FUNC("can't find last new alternative instruction",
10160 + special_alt->new_sec, special_alt->new_off);
10161 + return -1;
10162 + }
10163 +
10164 + if (fake_jump)
10165 + list_add(&fake_jump->list, &last_new_insn->list);
10166 +
10167 + return 0;
10168 +}
10169 +
10170 +/*
10171 + * A jump table entry can either convert a nop to a jump or a jump to a nop.
10172 + * If the original instruction is a jump, make the alt entry an effective nop
10173 + * by just skipping the original instruction.
10174 + */
10175 +static int handle_jump_alt(struct objtool_file *file,
10176 + struct special_alt *special_alt,
10177 + struct instruction *orig_insn,
10178 + struct instruction **new_insn)
10179 +{
10180 + if (orig_insn->type == INSN_NOP)
10181 + return 0;
10182 +
10183 + if (orig_insn->type != INSN_JUMP_UNCONDITIONAL) {
10184 + WARN_FUNC("unsupported instruction at jump label",
10185 + orig_insn->sec, orig_insn->offset);
10186 + return -1;
10187 + }
10188 +
10189 + *new_insn = list_next_entry(orig_insn, list);
10190 + return 0;
10191 +}
10192 +
10193 +/*
10194 + * Read all the special sections which have alternate instructions which can be
10195 + * patched in or redirected to at runtime. Each instruction having alternate
10196 + * instruction(s) has them added to its insn->alts list, which will be
10197 + * traversed in validate_branch().
10198 + */
10199 +static int add_special_section_alts(struct objtool_file *file)
10200 +{
10201 + struct list_head special_alts;
10202 + struct instruction *orig_insn, *new_insn;
10203 + struct special_alt *special_alt, *tmp;
10204 + struct alternative *alt;
10205 + int ret;
10206 +
10207 + ret = special_get_alts(file->elf, &special_alts);
10208 + if (ret)
10209 + return ret;
10210 +
10211 + list_for_each_entry_safe(special_alt, tmp, &special_alts, list) {
10212 +
10213 + orig_insn = find_insn(file, special_alt->orig_sec,
10214 + special_alt->orig_off);
10215 + if (!orig_insn) {
10216 + WARN_FUNC("special: can't find orig instruction",
10217 + special_alt->orig_sec, special_alt->orig_off);
10218 + ret = -1;
10219 + goto out;
10220 + }
10221 +
10222 + new_insn = NULL;
10223 + if (!special_alt->group || special_alt->new_len) {
10224 + new_insn = find_insn(file, special_alt->new_sec,
10225 + special_alt->new_off);
10226 + if (!new_insn) {
10227 + WARN_FUNC("special: can't find new instruction",
10228 + special_alt->new_sec,
10229 + special_alt->new_off);
10230 + ret = -1;
10231 + goto out;
10232 + }
10233 + }
10234 +
10235 + if (special_alt->group) {
10236 + ret = handle_group_alt(file, special_alt, orig_insn,
10237 + &new_insn);
10238 + if (ret)
10239 + goto out;
10240 + } else if (special_alt->jump_or_nop) {
10241 + ret = handle_jump_alt(file, special_alt, orig_insn,
10242 + &new_insn);
10243 + if (ret)
10244 + goto out;
10245 + }
10246 +
10247 + alt = malloc(sizeof(*alt));
10248 + if (!alt) {
10249 + WARN("malloc failed");
10250 + ret = -1;
10251 + goto out;
10252 + }
10253 +
10254 + alt->insn = new_insn;
10255 + list_add_tail(&alt->list, &orig_insn->alts);
10256 +
10257 + list_del(&special_alt->list);
10258 + free(special_alt);
10259 + }
10260 +
10261 +out:
10262 + return ret;
10263 +}
10264 +
10265 +static int add_switch_table(struct objtool_file *file, struct instruction *insn,
10266 + struct rela *table, struct rela *next_table)
10267 +{
10268 + struct rela *rela = table;
10269 + struct instruction *alt_insn;
10270 + struct alternative *alt;
10271 + struct symbol *pfunc = insn->func->pfunc;
10272 + unsigned int prev_offset = 0;
10273 +
10274 + list_for_each_entry_from(rela, &file->rodata->rela->rela_list, list) {
10275 + if (rela == next_table)
10276 + break;
10277 +
10278 + /* Make sure the switch table entries are consecutive: */
10279 + if (prev_offset && rela->offset != prev_offset + 8)
10280 + break;
10281 +
10282 + /* Detect function pointers from contiguous objects: */
10283 + if (rela->sym->sec == pfunc->sec &&
10284 + rela->addend == pfunc->offset)
10285 + break;
10286 +
10287 + alt_insn = find_insn(file, rela->sym->sec, rela->addend);
10288 + if (!alt_insn)
10289 + break;
10290 +
10291 + /* Make sure the jmp dest is in the function or subfunction: */
10292 + if (alt_insn->func->pfunc != pfunc)
10293 + break;
10294 +
10295 + alt = malloc(sizeof(*alt));
10296 + if (!alt) {
10297 + WARN("malloc failed");
10298 + return -1;
10299 + }
10300 +
10301 + alt->insn = alt_insn;
10302 + list_add_tail(&alt->list, &insn->alts);
10303 + prev_offset = rela->offset;
10304 + }
10305 +
10306 + if (!prev_offset) {
10307 + WARN_FUNC("can't find switch jump table",
10308 + insn->sec, insn->offset);
10309 + return -1;
10310 + }
10311 +
10312 + return 0;
10313 +}
10314 +
10315 +/*
10316 + * find_switch_table() - Given a dynamic jump, find the switch jump table in
10317 + * .rodata associated with it.
10318 + *
10319 + * There are 3 basic patterns:
10320 + *
10321 + * 1. jmpq *[rodata addr](,%reg,8)
10322 + *
10323 + * This is the most common case by far. It jumps to an address in a simple
10324 + * jump table which is stored in .rodata.
10325 + *
10326 + * 2. jmpq *[rodata addr](%rip)
10327 + *
10328 + * This is caused by a rare GCC quirk, currently only seen in three driver
10329 + * functions in the kernel, only with certain obscure non-distro configs.
10330 + *
10331 + * As part of an optimization, GCC makes a copy of an existing switch jump
10332 + * table, modifies it, and then hard-codes the jump (albeit with an indirect
10333 + * jump) to use a single entry in the table. The rest of the jump table and
10334 + * some of its jump targets remain as dead code.
10335 + *
10336 + * In such a case we can just crudely ignore all unreachable instruction
10337 + * warnings for the entire object file. Ideally we would just ignore them
10338 + * for the function, but that would require redesigning the code quite a
10339 + * bit. And honestly that's just not worth doing: unreachable instruction
10340 + * warnings are of questionable value anyway, and this is such a rare issue.
10341 + *
10342 + * 3. mov [rodata addr],%reg1
10343 + * ... some instructions ...
10344 + * jmpq *(%reg1,%reg2,8)
10345 + *
10346 + * This is a fairly uncommon pattern which is new for GCC 6. As of this
10347 + * writing, there are 11 occurrences of it in the allmodconfig kernel.
10348 + *
10349 + * As of GCC 7 there are quite a few more of these and the 'in between' code
10350 + * is significant. Esp. with KASAN enabled some of the code between the mov
10351 + * and jmpq uses .rodata itself, which can confuse things.
10352 + *
10353 + * TODO: Once we have DWARF CFI and smarter instruction decoding logic,
10354 + * ensure the same register is used in the mov and jump instructions.
10355 + *
10356 + * NOTE: RETPOLINE made it harder still to decode dynamic jumps.
10357 + */
10358 +static struct rela *find_switch_table(struct objtool_file *file,
10359 + struct symbol *func,
10360 + struct instruction *insn)
10361 +{
10362 + struct rela *text_rela, *rodata_rela;
10363 + struct instruction *orig_insn = insn;
10364 + unsigned long table_offset;
10365 +
10366 + /*
10367 + * Backward search using the @first_jump_src links, these help avoid
10368 + * much of the 'in between' code. Which avoids us getting confused by
10369 + * it.
10370 + */
10371 + for (;
10372 + &insn->list != &file->insn_list &&
10373 + insn->sec == func->sec &&
10374 + insn->offset >= func->offset;
10375 +
10376 + insn = insn->first_jump_src ?: list_prev_entry(insn, list)) {
10377 +
10378 + if (insn != orig_insn && insn->type == INSN_JUMP_DYNAMIC)
10379 + break;
10380 +
10381 + /* allow small jumps within the range */
10382 + if (insn->type == INSN_JUMP_UNCONDITIONAL &&
10383 + insn->jump_dest &&
10384 + (insn->jump_dest->offset <= insn->offset ||
10385 + insn->jump_dest->offset > orig_insn->offset))
10386 + break;
10387 +
10388 + /* look for a relocation which references .rodata */
10389 + text_rela = find_rela_by_dest_range(insn->sec, insn->offset,
10390 + insn->len);
10391 + if (!text_rela || text_rela->sym != file->rodata->sym)
10392 + continue;
10393 +
10394 + table_offset = text_rela->addend;
10395 + if (text_rela->type == R_X86_64_PC32)
10396 + table_offset += 4;
10397 +
10398 + /*
10399 + * Make sure the .rodata address isn't associated with a
10400 + * symbol. gcc jump tables are anonymous data.
10401 + */
10402 + if (find_symbol_containing(file->rodata, table_offset))
10403 + continue;
10404 +
10405 + rodata_rela = find_rela_by_dest(file->rodata, table_offset);
10406 + if (rodata_rela) {
10407 + /*
10408 + * Use of RIP-relative switch jumps is quite rare, and
10409 + * indicates a rare GCC quirk/bug which can leave dead
10410 + * code behind.
10411 + */
10412 + if (text_rela->type == R_X86_64_PC32)
10413 + file->ignore_unreachables = true;
10414 +
10415 + return rodata_rela;
10416 + }
10417 + }
10418 +
10419 + return NULL;
10420 +}
10421 +
10422 +
10423 +static int add_func_switch_tables(struct objtool_file *file,
10424 + struct symbol *func)
10425 +{
10426 + struct instruction *insn, *last = NULL, *prev_jump = NULL;
10427 + struct rela *rela, *prev_rela = NULL;
10428 + int ret;
10429 +
10430 + func_for_each_insn_all(file, func, insn) {
10431 + if (!last)
10432 + last = insn;
10433 +
10434 + /*
10435 + * Store back-pointers for unconditional forward jumps such
10436 + * that find_switch_table() can back-track using those and
10437 + * avoid some potentially confusing code.
10438 + */
10439 + if (insn->type == INSN_JUMP_UNCONDITIONAL && insn->jump_dest &&
10440 + insn->offset > last->offset &&
10441 + insn->jump_dest->offset > insn->offset &&
10442 + !insn->jump_dest->first_jump_src) {
10443 +
10444 + insn->jump_dest->first_jump_src = insn;
10445 + last = insn->jump_dest;
10446 + }
10447 +
10448 + if (insn->type != INSN_JUMP_DYNAMIC)
10449 + continue;
10450 +
10451 + rela = find_switch_table(file, func, insn);
10452 + if (!rela)
10453 + continue;
10454 +
10455 + /*
10456 + * We found a switch table, but we don't know yet how big it
10457 + * is. Don't add it until we reach the end of the function or
10458 + * the beginning of another switch table in the same function.
10459 + */
10460 + if (prev_jump) {
10461 + ret = add_switch_table(file, prev_jump, prev_rela, rela);
10462 + if (ret)
10463 + return ret;
10464 + }
10465 +
10466 + prev_jump = insn;
10467 + prev_rela = rela;
10468 + }
10469 +
10470 + if (prev_jump) {
10471 + ret = add_switch_table(file, prev_jump, prev_rela, NULL);
10472 + if (ret)
10473 + return ret;
10474 + }
10475 +
10476 + return 0;
10477 +}
10478 +
10479 +/*
10480 + * For some switch statements, gcc generates a jump table in the .rodata
10481 + * section which contains a list of addresses within the function to jump to.
10482 + * This finds these jump tables and adds them to the insn->alts lists.
10483 + */
10484 +static int add_switch_table_alts(struct objtool_file *file)
10485 +{
10486 + struct section *sec;
10487 + struct symbol *func;
10488 + int ret;
10489 +
10490 + if (!file->rodata || !file->rodata->rela)
10491 + return 0;
10492 +
10493 + for_each_sec(file, sec) {
10494 + list_for_each_entry(func, &sec->symbol_list, list) {
10495 + if (func->type != STT_FUNC)
10496 + continue;
10497 +
10498 + ret = add_func_switch_tables(file, func);
10499 + if (ret)
10500 + return ret;
10501 + }
10502 + }
10503 +
10504 + return 0;
10505 +}
10506 +
10507 +static int read_unwind_hints(struct objtool_file *file)
10508 +{
10509 + struct section *sec, *relasec;
10510 + struct rela *rela;
10511 + struct unwind_hint *hint;
10512 + struct instruction *insn;
10513 + struct cfi_reg *cfa;
10514 + int i;
10515 +
10516 + sec = find_section_by_name(file->elf, ".discard.unwind_hints");
10517 + if (!sec)
10518 + return 0;
10519 +
10520 + relasec = sec->rela;
10521 + if (!relasec) {
10522 + WARN("missing .rela.discard.unwind_hints section");
10523 + return -1;
10524 + }
10525 +
10526 + if (sec->len % sizeof(struct unwind_hint)) {
10527 + WARN("struct unwind_hint size mismatch");
10528 + return -1;
10529 + }
10530 +
10531 + file->hints = true;
10532 +
10533 + for (i = 0; i < sec->len / sizeof(struct unwind_hint); i++) {
10534 + hint = (struct unwind_hint *)sec->data->d_buf + i;
10535 +
10536 + rela = find_rela_by_dest(sec, i * sizeof(*hint));
10537 + if (!rela) {
10538 + WARN("can't find rela for unwind_hints[%d]", i);
10539 + return -1;
10540 + }
10541 +
10542 + insn = find_insn(file, rela->sym->sec, rela->addend);
10543 + if (!insn) {
10544 + WARN("can't find insn for unwind_hints[%d]", i);
10545 + return -1;
10546 + }
10547 +
10548 + cfa = &insn->state.cfa;
10549 +
10550 + if (hint->type == UNWIND_HINT_TYPE_SAVE) {
10551 + insn->save = true;
10552 + continue;
10553 +
10554 + } else if (hint->type == UNWIND_HINT_TYPE_RESTORE) {
10555 + insn->restore = true;
10556 + insn->hint = true;
10557 + continue;
10558 + }
10559 +
10560 + insn->hint = true;
10561 +
10562 + switch (hint->sp_reg) {
10563 + case ORC_REG_UNDEFINED:
10564 + cfa->base = CFI_UNDEFINED;
10565 + break;
10566 + case ORC_REG_SP:
10567 + cfa->base = CFI_SP;
10568 + break;
10569 + case ORC_REG_BP:
10570 + cfa->base = CFI_BP;
10571 + break;
10572 + case ORC_REG_SP_INDIRECT:
10573 + cfa->base = CFI_SP_INDIRECT;
10574 + break;
10575 + case ORC_REG_R10:
10576 + cfa->base = CFI_R10;
10577 + break;
10578 + case ORC_REG_R13:
10579 + cfa->base = CFI_R13;
10580 + break;
10581 + case ORC_REG_DI:
10582 + cfa->base = CFI_DI;
10583 + break;
10584 + case ORC_REG_DX:
10585 + cfa->base = CFI_DX;
10586 + break;
10587 + default:
10588 + WARN_FUNC("unsupported unwind_hint sp base reg %d",
10589 + insn->sec, insn->offset, hint->sp_reg);
10590 + return -1;
10591 + }
10592 +
10593 + cfa->offset = hint->sp_offset;
10594 + insn->state.type = hint->type;
10595 + }
10596 +
10597 + return 0;
10598 +}
10599 +
10600 +static int read_retpoline_hints(struct objtool_file *file)
10601 +{
10602 + struct section *sec;
10603 + struct instruction *insn;
10604 + struct rela *rela;
10605 +
10606 + sec = find_section_by_name(file->elf, ".rela.discard.retpoline_safe");
10607 + if (!sec)
10608 + return 0;
10609 +
10610 + list_for_each_entry(rela, &sec->rela_list, list) {
10611 + if (rela->sym->type != STT_SECTION) {
10612 + WARN("unexpected relocation symbol type in %s", sec->name);
10613 + return -1;
10614 + }
10615 +
10616 + insn = find_insn(file, rela->sym->sec, rela->addend);
10617 + if (!insn) {
10618 + WARN("bad .discard.retpoline_safe entry");
10619 + return -1;
10620 + }
10621 +
10622 + if (insn->type != INSN_JUMP_DYNAMIC &&
10623 + insn->type != INSN_CALL_DYNAMIC) {
10624 + WARN_FUNC("retpoline_safe hint not an indirect jump/call",
10625 + insn->sec, insn->offset);
10626 + return -1;
10627 + }
10628 +
10629 + insn->retpoline_safe = true;
10630 + }
10631 +
10632 + return 0;
10633 +}
10634 +
10635 +static int decode_sections(struct objtool_file *file)
10636 +{
10637 + int ret;
10638 +
10639 + ret = decode_instructions(file);
10640 + if (ret)
10641 + return ret;
10642 +
10643 + ret = add_dead_ends(file);
10644 + if (ret)
10645 + return ret;
10646 +
10647 + add_ignores(file);
10648 +
10649 + ret = add_nospec_ignores(file);
10650 + if (ret)
10651 + return ret;
10652 +
10653 + ret = add_jump_destinations(file);
10654 + if (ret)
10655 + return ret;
10656 +
10657 + ret = add_special_section_alts(file);
10658 + if (ret)
10659 + return ret;
10660 +
10661 + ret = add_call_destinations(file);
10662 + if (ret)
10663 + return ret;
10664 +
10665 + ret = add_switch_table_alts(file);
10666 + if (ret)
10667 + return ret;
10668 +
10669 + ret = read_unwind_hints(file);
10670 + if (ret)
10671 + return ret;
10672 +
10673 + ret = read_retpoline_hints(file);
10674 + if (ret)
10675 + return ret;
10676 +
10677 + return 0;
10678 +}
10679 +
10680 +static bool is_fentry_call(struct instruction *insn)
10681 +{
10682 + if (insn->type == INSN_CALL &&
10683 + insn->call_dest->type == STT_NOTYPE &&
10684 + !strcmp(insn->call_dest->name, "__fentry__"))
10685 + return true;
10686 +
10687 + return false;
10688 +}
10689 +
10690 +static bool has_modified_stack_frame(struct insn_state *state)
10691 +{
10692 + int i;
10693 +
10694 + if (state->cfa.base != initial_func_cfi.cfa.base ||
10695 + state->cfa.offset != initial_func_cfi.cfa.offset ||
10696 + state->stack_size != initial_func_cfi.cfa.offset ||
10697 + state->drap)
10698 + return true;
10699 +
10700 + for (i = 0; i < CFI_NUM_REGS; i++)
10701 + if (state->regs[i].base != initial_func_cfi.regs[i].base ||
10702 + state->regs[i].offset != initial_func_cfi.regs[i].offset)
10703 + return true;
10704 +
10705 + return false;
10706 +}
10707 +
10708 +static bool has_valid_stack_frame(struct insn_state *state)
10709 +{
10710 + if (state->cfa.base == CFI_BP && state->regs[CFI_BP].base == CFI_CFA &&
10711 + state->regs[CFI_BP].offset == -16)
10712 + return true;
10713 +
10714 + if (state->drap && state->regs[CFI_BP].base == CFI_BP)
10715 + return true;
10716 +
10717 + return false;
10718 +}
10719 +
10720 +static int update_insn_state_regs(struct instruction *insn, struct insn_state *state)
10721 +{
10722 + struct cfi_reg *cfa = &state->cfa;
10723 + struct stack_op *op = &insn->stack_op;
10724 +
10725 + if (cfa->base != CFI_SP)
10726 + return 0;
10727 +
10728 + /* push */
10729 + if (op->dest.type == OP_DEST_PUSH)
10730 + cfa->offset += 8;
10731 +
10732 + /* pop */
10733 + if (op->src.type == OP_SRC_POP)
10734 + cfa->offset -= 8;
10735 +
10736 + /* add immediate to sp */
10737 + if (op->dest.type == OP_DEST_REG && op->src.type == OP_SRC_ADD &&
10738 + op->dest.reg == CFI_SP && op->src.reg == CFI_SP)
10739 + cfa->offset -= op->src.offset;
10740 +
10741 + return 0;
10742 +}
10743 +
10744 +static void save_reg(struct insn_state *state, unsigned char reg, int base,
10745 + int offset)
10746 +{
10747 + if (arch_callee_saved_reg(reg) &&
10748 + state->regs[reg].base == CFI_UNDEFINED) {
10749 + state->regs[reg].base = base;
10750 + state->regs[reg].offset = offset;
10751 + }
10752 +}
10753 +
10754 +static void restore_reg(struct insn_state *state, unsigned char reg)
10755 +{
10756 + state->regs[reg].base = CFI_UNDEFINED;
10757 + state->regs[reg].offset = 0;
10758 +}
10759 +
10760 +/*
10761 + * A note about DRAP stack alignment:
10762 + *
10763 + * GCC has the concept of a DRAP register, which is used to help keep track of
10764 + * the stack pointer when aligning the stack. r10 or r13 is used as the DRAP
10765 + * register. The typical DRAP pattern is:
10766 + *
10767 + * 4c 8d 54 24 08 lea 0x8(%rsp),%r10
10768 + * 48 83 e4 c0 and $0xffffffffffffffc0,%rsp
10769 + * 41 ff 72 f8 pushq -0x8(%r10)
10770 + * 55 push %rbp
10771 + * 48 89 e5 mov %rsp,%rbp
10772 + * (more pushes)
10773 + * 41 52 push %r10
10774 + * ...
10775 + * 41 5a pop %r10
10776 + * (more pops)
10777 + * 5d pop %rbp
10778 + * 49 8d 62 f8 lea -0x8(%r10),%rsp
10779 + * c3 retq
10780 + *
10781 + * There are some variations in the epilogues, like:
10782 + *
10783 + * 5b pop %rbx
10784 + * 41 5a pop %r10
10785 + * 41 5c pop %r12
10786 + * 41 5d pop %r13
10787 + * 41 5e pop %r14
10788 + * c9 leaveq
10789 + * 49 8d 62 f8 lea -0x8(%r10),%rsp
10790 + * c3 retq
10791 + *
10792 + * and:
10793 + *
10794 + * 4c 8b 55 e8 mov -0x18(%rbp),%r10
10795 + * 48 8b 5d e0 mov -0x20(%rbp),%rbx
10796 + * 4c 8b 65 f0 mov -0x10(%rbp),%r12
10797 + * 4c 8b 6d f8 mov -0x8(%rbp),%r13
10798 + * c9 leaveq
10799 + * 49 8d 62 f8 lea -0x8(%r10),%rsp
10800 + * c3 retq
10801 + *
10802 + * Sometimes r13 is used as the DRAP register, in which case it's saved and
10803 + * restored beforehand:
10804 + *
10805 + * 41 55 push %r13
10806 + * 4c 8d 6c 24 10 lea 0x10(%rsp),%r13
10807 + * 48 83 e4 f0 and $0xfffffffffffffff0,%rsp
10808 + * ...
10809 + * 49 8d 65 f0 lea -0x10(%r13),%rsp
10810 + * 41 5d pop %r13
10811 + * c3 retq
10812 + */
10813 +static int update_insn_state(struct instruction *insn, struct insn_state *state)
10814 +{
10815 + struct stack_op *op = &insn->stack_op;
10816 + struct cfi_reg *cfa = &state->cfa;
10817 + struct cfi_reg *regs = state->regs;
10818 +
10819 + /* stack operations don't make sense with an undefined CFA */
10820 + if (cfa->base == CFI_UNDEFINED) {
10821 + if (insn->func) {
10822 + WARN_FUNC("undefined stack state", insn->sec, insn->offset);
10823 + return -1;
10824 + }
10825 + return 0;
10826 + }
10827 +
10828 + if (state->type == ORC_TYPE_REGS || state->type == ORC_TYPE_REGS_IRET)
10829 + return update_insn_state_regs(insn, state);
10830 +
10831 + switch (op->dest.type) {
10832 +
10833 + case OP_DEST_REG:
10834 + switch (op->src.type) {
10835 +
10836 + case OP_SRC_REG:
10837 + if (op->src.reg == CFI_SP && op->dest.reg == CFI_BP &&
10838 + cfa->base == CFI_SP &&
10839 + regs[CFI_BP].base == CFI_CFA &&
10840 + regs[CFI_BP].offset == -cfa->offset) {
10841 +
10842 + /* mov %rsp, %rbp */
10843 + cfa->base = op->dest.reg;
10844 + state->bp_scratch = false;
10845 + }
10846 +
10847 + else if (op->src.reg == CFI_SP &&
10848 + op->dest.reg == CFI_BP && state->drap) {
10849 +
10850 + /* drap: mov %rsp, %rbp */
10851 + regs[CFI_BP].base = CFI_BP;
10852 + regs[CFI_BP].offset = -state->stack_size;
10853 + state->bp_scratch = false;
10854 + }
10855 +
10856 + else if (op->src.reg == CFI_SP && cfa->base == CFI_SP) {
10857 +
10858 + /*
10859 + * mov %rsp, %reg
10860 + *
10861 + * This is needed for the rare case where GCC
10862 + * does:
10863 + *
10864 + * mov %rsp, %rax
10865 + * ...
10866 + * mov %rax, %rsp
10867 + */
10868 + state->vals[op->dest.reg].base = CFI_CFA;
10869 + state->vals[op->dest.reg].offset = -state->stack_size;
10870 + }
10871 +
10872 + else if (op->src.reg == CFI_BP && op->dest.reg == CFI_SP &&
10873 + cfa->base == CFI_BP) {
10874 +
10875 + /*
10876 + * mov %rbp, %rsp
10877 + *
10878 + * Restore the original stack pointer (Clang).
10879 + */
10880 + state->stack_size = -state->regs[CFI_BP].offset;
10881 + }
10882 +
10883 + else if (op->dest.reg == cfa->base) {
10884 +
10885 + /* mov %reg, %rsp */
10886 + if (cfa->base == CFI_SP &&
10887 + state->vals[op->src.reg].base == CFI_CFA) {
10888 +
10889 + /*
10890 + * This is needed for the rare case
10891 + * where GCC does something dumb like:
10892 + *
10893 + * lea 0x8(%rsp), %rcx
10894 + * ...
10895 + * mov %rcx, %rsp
10896 + */
10897 + cfa->offset = -state->vals[op->src.reg].offset;
10898 + state->stack_size = cfa->offset;
10899 +
10900 + } else {
10901 + cfa->base = CFI_UNDEFINED;
10902 + cfa->offset = 0;
10903 + }
10904 + }
10905 +
10906 + break;
10907 +
10908 + case OP_SRC_ADD:
10909 + if (op->dest.reg == CFI_SP && op->src.reg == CFI_SP) {
10910 +
10911 + /* add imm, %rsp */
10912 + state->stack_size -= op->src.offset;
10913 + if (cfa->base == CFI_SP)
10914 + cfa->offset -= op->src.offset;
10915 + break;
10916 + }
10917 +
10918 + if (op->dest.reg == CFI_SP && op->src.reg == CFI_BP) {
10919 +
10920 + /* lea disp(%rbp), %rsp */
10921 + state->stack_size = -(op->src.offset + regs[CFI_BP].offset);
10922 + break;
10923 + }
10924 +
10925 + if (op->src.reg == CFI_SP && cfa->base == CFI_SP) {
10926 +
10927 + /* drap: lea disp(%rsp), %drap */
10928 + state->drap_reg = op->dest.reg;
10929 +
10930 + /*
10931 + * lea disp(%rsp), %reg
10932 + *
10933 + * This is needed for the rare case where GCC
10934 + * does something dumb like:
10935 + *
10936 + * lea 0x8(%rsp), %rcx
10937 + * ...
10938 + * mov %rcx, %rsp
10939 + */
10940 + state->vals[op->dest.reg].base = CFI_CFA;
10941 + state->vals[op->dest.reg].offset = \
10942 + -state->stack_size + op->src.offset;
10943 +
10944 + break;
10945 + }
10946 +
10947 + if (state->drap && op->dest.reg == CFI_SP &&
10948 + op->src.reg == state->drap_reg) {
10949 +
10950 + /* drap: lea disp(%drap), %rsp */
10951 + cfa->base = CFI_SP;
10952 + cfa->offset = state->stack_size = -op->src.offset;
10953 + state->drap_reg = CFI_UNDEFINED;
10954 + state->drap = false;
10955 + break;
10956 + }
10957 +
10958 + if (op->dest.reg == state->cfa.base) {
10959 + WARN_FUNC("unsupported stack register modification",
10960 + insn->sec, insn->offset);
10961 + return -1;
10962 + }
10963 +
10964 + break;
10965 +
10966 + case OP_SRC_AND:
10967 + if (op->dest.reg != CFI_SP ||
10968 + (state->drap_reg != CFI_UNDEFINED && cfa->base != CFI_SP) ||
10969 + (state->drap_reg == CFI_UNDEFINED && cfa->base != CFI_BP)) {
10970 + WARN_FUNC("unsupported stack pointer realignment",
10971 + insn->sec, insn->offset);
10972 + return -1;
10973 + }
10974 +
10975 + if (state->drap_reg != CFI_UNDEFINED) {
10976 + /* drap: and imm, %rsp */
10977 + cfa->base = state->drap_reg;
10978 + cfa->offset = state->stack_size = 0;
10979 + state->drap = true;
10980 + }
10981 +
10982 + /*
10983 + * Older versions of GCC (4.8ish) realign the stack
10984 + * without DRAP, with a frame pointer.
10985 + */
10986 +
10987 + break;
10988 +
10989 + case OP_SRC_POP:
10990 + if (!state->drap && op->dest.type == OP_DEST_REG &&
10991 + op->dest.reg == cfa->base) {
10992 +
10993 + /* pop %rbp */
10994 + cfa->base = CFI_SP;
10995 + }
10996 +
10997 + if (state->drap && cfa->base == CFI_BP_INDIRECT &&
10998 + op->dest.type == OP_DEST_REG &&
10999 + op->dest.reg == state->drap_reg &&
11000 + state->drap_offset == -state->stack_size) {
11001 +
11002 + /* drap: pop %drap */
11003 + cfa->base = state->drap_reg;
11004 + cfa->offset = 0;
11005 + state->drap_offset = -1;
11006 +
11007 + } else if (regs[op->dest.reg].offset == -state->stack_size) {
11008 +
11009 + /* pop %reg */
11010 + restore_reg(state, op->dest.reg);
11011 + }
11012 +
11013 + state->stack_size -= 8;
11014 + if (cfa->base == CFI_SP)
11015 + cfa->offset -= 8;
11016 +
11017 + break;
11018 +
11019 + case OP_SRC_REG_INDIRECT:
11020 + if (state->drap && op->src.reg == CFI_BP &&
11021 + op->src.offset == state->drap_offset) {
11022 +
11023 + /* drap: mov disp(%rbp), %drap */
11024 + cfa->base = state->drap_reg;
11025 + cfa->offset = 0;
11026 + state->drap_offset = -1;
11027 + }
11028 +
11029 + if (state->drap && op->src.reg == CFI_BP &&
11030 + op->src.offset == regs[op->dest.reg].offset) {
11031 +
11032 + /* drap: mov disp(%rbp), %reg */
11033 + restore_reg(state, op->dest.reg);
11034 +
11035 + } else if (op->src.reg == cfa->base &&
11036 + op->src.offset == regs[op->dest.reg].offset + cfa->offset) {
11037 +
11038 + /* mov disp(%rbp), %reg */
11039 + /* mov disp(%rsp), %reg */
11040 + restore_reg(state, op->dest.reg);
11041 + }
11042 +
11043 + break;
11044 +
11045 + default:
11046 + WARN_FUNC("unknown stack-related instruction",
11047 + insn->sec, insn->offset);
11048 + return -1;
11049 + }
11050 +
11051 + break;
11052 +
11053 + case OP_DEST_PUSH:
11054 + state->stack_size += 8;
11055 + if (cfa->base == CFI_SP)
11056 + cfa->offset += 8;
11057 +
11058 + if (op->src.type != OP_SRC_REG)
11059 + break;
11060 +
11061 + if (state->drap) {
11062 + if (op->src.reg == cfa->base && op->src.reg == state->drap_reg) {
11063 +
11064 + /* drap: push %drap */
11065 + cfa->base = CFI_BP_INDIRECT;
11066 + cfa->offset = -state->stack_size;
11067 +
11068 + /* save drap so we know when to restore it */
11069 + state->drap_offset = -state->stack_size;
11070 +
11071 + } else if (op->src.reg == CFI_BP && cfa->base == state->drap_reg) {
11072 +
11073 + /* drap: push %rbp */
11074 + state->stack_size = 0;
11075 +
11076 + } else if (regs[op->src.reg].base == CFI_UNDEFINED) {
11077 +
11078 + /* drap: push %reg */
11079 + save_reg(state, op->src.reg, CFI_BP, -state->stack_size);
11080 + }
11081 +
11082 + } else {
11083 +
11084 + /* push %reg */
11085 + save_reg(state, op->src.reg, CFI_CFA, -state->stack_size);
11086 + }
11087 +
11088 + /* detect when asm code uses rbp as a scratch register */
11089 + if (!no_fp && insn->func && op->src.reg == CFI_BP &&
11090 + cfa->base != CFI_BP)
11091 + state->bp_scratch = true;
11092 + break;
11093 +
11094 + case OP_DEST_REG_INDIRECT:
11095 +
11096 + if (state->drap) {
11097 + if (op->src.reg == cfa->base && op->src.reg == state->drap_reg) {
11098 +
11099 + /* drap: mov %drap, disp(%rbp) */
11100 + cfa->base = CFI_BP_INDIRECT;
11101 + cfa->offset = op->dest.offset;
11102 +
11103 + /* save drap offset so we know when to restore it */
11104 + state->drap_offset = op->dest.offset;
11105 + }
11106 +
11107 + else if (regs[op->src.reg].base == CFI_UNDEFINED) {
11108 +
11109 + /* drap: mov reg, disp(%rbp) */
11110 + save_reg(state, op->src.reg, CFI_BP, op->dest.offset);
11111 + }
11112 +
11113 + } else if (op->dest.reg == cfa->base) {
11114 +
11115 + /* mov reg, disp(%rbp) */
11116 + /* mov reg, disp(%rsp) */
11117 + save_reg(state, op->src.reg, CFI_CFA,
11118 + op->dest.offset - state->cfa.offset);
11119 + }
11120 +
11121 + break;
11122 +
11123 + case OP_DEST_LEAVE:
11124 + if ((!state->drap && cfa->base != CFI_BP) ||
11125 + (state->drap && cfa->base != state->drap_reg)) {
11126 + WARN_FUNC("leave instruction with modified stack frame",
11127 + insn->sec, insn->offset);
11128 + return -1;
11129 + }
11130 +
11131 + /* leave (mov %rbp, %rsp; pop %rbp) */
11132 +
11133 + state->stack_size = -state->regs[CFI_BP].offset - 8;
11134 + restore_reg(state, CFI_BP);
11135 +
11136 + if (!state->drap) {
11137 + cfa->base = CFI_SP;
11138 + cfa->offset -= 8;
11139 + }
11140 +
11141 + break;
11142 +
11143 + case OP_DEST_MEM:
11144 + if (op->src.type != OP_SRC_POP) {
11145 + WARN_FUNC("unknown stack-related memory operation",
11146 + insn->sec, insn->offset);
11147 + return -1;
11148 + }
11149 +
11150 + /* pop mem */
11151 + state->stack_size -= 8;
11152 + if (cfa->base == CFI_SP)
11153 + cfa->offset -= 8;
11154 +
11155 + break;
11156 +
11157 + default:
11158 + WARN_FUNC("unknown stack-related instruction",
11159 + insn->sec, insn->offset);
11160 + return -1;
11161 + }
11162 +
11163 + return 0;
11164 +}
11165 +
11166 +static bool insn_state_match(struct instruction *insn, struct insn_state *state)
11167 +{
11168 + struct insn_state *state1 = &insn->state, *state2 = state;
11169 + int i;
11170 +
11171 + if (memcmp(&state1->cfa, &state2->cfa, sizeof(state1->cfa))) {
11172 + WARN_FUNC("stack state mismatch: cfa1=%d%+d cfa2=%d%+d",
11173 + insn->sec, insn->offset,
11174 + state1->cfa.base, state1->cfa.offset,
11175 + state2->cfa.base, state2->cfa.offset);
11176 +
11177 + } else if (memcmp(&state1->regs, &state2->regs, sizeof(state1->regs))) {
11178 + for (i = 0; i < CFI_NUM_REGS; i++) {
11179 + if (!memcmp(&state1->regs[i], &state2->regs[i],
11180 + sizeof(struct cfi_reg)))
11181 + continue;
11182 +
11183 + WARN_FUNC("stack state mismatch: reg1[%d]=%d%+d reg2[%d]=%d%+d",
11184 + insn->sec, insn->offset,
11185 + i, state1->regs[i].base, state1->regs[i].offset,
11186 + i, state2->regs[i].base, state2->regs[i].offset);
11187 + break;
11188 + }
11189 +
11190 + } else if (state1->type != state2->type) {
11191 + WARN_FUNC("stack state mismatch: type1=%d type2=%d",
11192 + insn->sec, insn->offset, state1->type, state2->type);
11193 +
11194 + } else if (state1->drap != state2->drap ||
11195 + (state1->drap && state1->drap_reg != state2->drap_reg) ||
11196 + (state1->drap && state1->drap_offset != state2->drap_offset)) {
11197 + WARN_FUNC("stack state mismatch: drap1=%d(%d,%d) drap2=%d(%d,%d)",
11198 + insn->sec, insn->offset,
11199 + state1->drap, state1->drap_reg, state1->drap_offset,
11200 + state2->drap, state2->drap_reg, state2->drap_offset);
11201 +
11202 + } else
11203 + return true;
11204 +
11205 + return false;
11206 +}
11207 +
11208 +/*
11209 + * Follow the branch starting at the given instruction, and recursively follow
11210 + * any other branches (jumps). Meanwhile, track the frame pointer state at
11211 + * each instruction and validate all the rules described in
11212 + * tools/objtool/Documentation/stack-validation.txt.
11213 + */
11214 +static int validate_branch(struct objtool_file *file, struct instruction *first,
11215 + struct insn_state state)
11216 +{
11217 + struct alternative *alt;
11218 + struct instruction *insn, *next_insn;
11219 + struct section *sec;
11220 + struct symbol *func = NULL;
11221 + int ret;
11222 +
11223 + insn = first;
11224 + sec = insn->sec;
11225 +
11226 + if (insn->alt_group && list_empty(&insn->alts)) {
11227 + WARN_FUNC("don't know how to handle branch to middle of alternative instruction group",
11228 + sec, insn->offset);
11229 + return 1;
11230 + }
11231 +
11232 + while (1) {
11233 + next_insn = next_insn_same_sec(file, insn);
11234 +
11235 + if (file->c_file && func && insn->func && func != insn->func->pfunc) {
11236 + WARN("%s() falls through to next function %s()",
11237 + func->name, insn->func->name);
11238 + return 1;
11239 + }
11240 +
11241 + func = insn->func ? insn->func->pfunc : NULL;
11242 +
11243 + if (func && insn->ignore) {
11244 + WARN_FUNC("BUG: why am I validating an ignored function?",
11245 + sec, insn->offset);
11246 + return 1;
11247 + }
11248 +
11249 + if (insn->visited) {
11250 + if (!insn->hint && !insn_state_match(insn, &state))
11251 + return 1;
11252 +
11253 + return 0;
11254 + }
11255 +
11256 + if (insn->hint) {
11257 + if (insn->restore) {
11258 + struct instruction *save_insn, *i;
11259 +
11260 + i = insn;
11261 + save_insn = NULL;
11262 + func_for_each_insn_continue_reverse(file, insn->func, i) {
11263 + if (i->save) {
11264 + save_insn = i;
11265 + break;
11266 + }
11267 + }
11268 +
11269 + if (!save_insn) {
11270 + WARN_FUNC("no corresponding CFI save for CFI restore",
11271 + sec, insn->offset);
11272 + return 1;
11273 + }
11274 +
11275 + if (!save_insn->visited) {
11276 + /*
11277 + * Oops, no state to copy yet.
11278 + * Hopefully we can reach this
11279 + * instruction from another branch
11280 + * after the save insn has been
11281 + * visited.
11282 + */
11283 + if (insn == first)
11284 + return 0;
11285 +
11286 + WARN_FUNC("objtool isn't smart enough to handle this CFI save/restore combo",
11287 + sec, insn->offset);
11288 + return 1;
11289 + }
11290 +
11291 + insn->state = save_insn->state;
11292 + }
11293 +
11294 + state = insn->state;
11295 +
11296 + } else
11297 + insn->state = state;
11298 +
11299 + insn->visited = true;
11300 +
11301 + if (!insn->ignore_alts) {
11302 + list_for_each_entry(alt, &insn->alts, list) {
11303 + ret = validate_branch(file, alt->insn, state);
11304 + if (ret)
11305 + return 1;
11306 + }
11307 + }
11308 +
11309 + switch (insn->type) {
11310 +
11311 + case INSN_RETURN:
11312 + if (func && has_modified_stack_frame(&state)) {
11313 + WARN_FUNC("return with modified stack frame",
11314 + sec, insn->offset);
11315 + return 1;
11316 + }
11317 +
11318 + if (state.bp_scratch) {
11319 + WARN("%s uses BP as a scratch register",
11320 + insn->func->name);
11321 + return 1;
11322 + }
11323 +
11324 + return 0;
11325 +
11326 + case INSN_CALL:
11327 + if (is_fentry_call(insn))
11328 + break;
11329 +
11330 + ret = dead_end_function(file, insn->call_dest);
11331 + if (ret == 1)
11332 + return 0;
11333 + if (ret == -1)
11334 + return 1;
11335 +
11336 + /* fallthrough */
11337 + case INSN_CALL_DYNAMIC:
11338 + if (!no_fp && func && !has_valid_stack_frame(&state)) {
11339 + WARN_FUNC("call without frame pointer save/setup",
11340 + sec, insn->offset);
11341 + return 1;
11342 + }
11343 + break;
11344 +
11345 + case INSN_JUMP_CONDITIONAL:
11346 + case INSN_JUMP_UNCONDITIONAL:
11347 + if (insn->jump_dest &&
11348 + (!func || !insn->jump_dest->func ||
11349 + insn->jump_dest->func->pfunc == func)) {
11350 + ret = validate_branch(file, insn->jump_dest,
11351 + state);
11352 + if (ret)
11353 + return 1;
11354 +
11355 + } else if (func && has_modified_stack_frame(&state)) {
11356 + WARN_FUNC("sibling call from callable instruction with modified stack frame",
11357 + sec, insn->offset);
11358 + return 1;
11359 + }
11360 +
11361 + if (insn->type == INSN_JUMP_UNCONDITIONAL)
11362 + return 0;
11363 +
11364 + break;
11365 +
11366 + case INSN_JUMP_DYNAMIC:
11367 + if (func && list_empty(&insn->alts) &&
11368 + has_modified_stack_frame(&state)) {
11369 + WARN_FUNC("sibling call from callable instruction with modified stack frame",
11370 + sec, insn->offset);
11371 + return 1;
11372 + }
11373 +
11374 + return 0;
11375 +
11376 + case INSN_CONTEXT_SWITCH:
11377 + if (func && (!next_insn || !next_insn->hint)) {
11378 + WARN_FUNC("unsupported instruction in callable function",
11379 + sec, insn->offset);
11380 + return 1;
11381 + }
11382 + return 0;
11383 +
11384 + case INSN_STACK:
11385 + if (update_insn_state(insn, &state))
11386 + return 1;
11387 +
11388 + break;
11389 +
11390 + default:
11391 + break;
11392 + }
11393 +
11394 + if (insn->dead_end)
11395 + return 0;
11396 +
11397 + if (!next_insn) {
11398 + if (state.cfa.base == CFI_UNDEFINED)
11399 + return 0;
11400 + WARN("%s: unexpected end of section", sec->name);
11401 + return 1;
11402 + }
11403 +
11404 + insn = next_insn;
11405 + }
11406 +
11407 + return 0;
11408 +}
11409 +
11410 +static int validate_unwind_hints(struct objtool_file *file)
11411 +{
11412 + struct instruction *insn;
11413 + int ret, warnings = 0;
11414 + struct insn_state state;
11415 +
11416 + if (!file->hints)
11417 + return 0;
11418 +
11419 + clear_insn_state(&state);
11420 +
11421 + for_each_insn(file, insn) {
11422 + if (insn->hint && !insn->visited) {
11423 + ret = validate_branch(file, insn, state);
11424 + warnings += ret;
11425 + }
11426 + }
11427 +
11428 + return warnings;
11429 +}
11430 +
11431 +static int validate_retpoline(struct objtool_file *file)
11432 +{
11433 + struct instruction *insn;
11434 + int warnings = 0;
11435 +
11436 + for_each_insn(file, insn) {
11437 + if (insn->type != INSN_JUMP_DYNAMIC &&
11438 + insn->type != INSN_CALL_DYNAMIC)
11439 + continue;
11440 +
11441 + if (insn->retpoline_safe)
11442 + continue;
11443 +
11444 + /*
11445 + * .init.text code is ran before userspace and thus doesn't
11446 + * strictly need retpolines, except for modules which are
11447 + * loaded late, they very much do need retpoline in their
11448 + * .init.text
11449 + */
11450 + if (!strcmp(insn->sec->name, ".init.text") && !module)
11451 + continue;
11452 +
11453 + WARN_FUNC("indirect %s found in RETPOLINE build",
11454 + insn->sec, insn->offset,
11455 + insn->type == INSN_JUMP_DYNAMIC ? "jump" : "call");
11456 +
11457 + warnings++;
11458 + }
11459 +
11460 + return warnings;
11461 +}
11462 +
11463 +static bool is_kasan_insn(struct instruction *insn)
11464 +{
11465 + return (insn->type == INSN_CALL &&
11466 + !strcmp(insn->call_dest->name, "__asan_handle_no_return"));
11467 +}
11468 +
11469 +static bool is_ubsan_insn(struct instruction *insn)
11470 +{
11471 + return (insn->type == INSN_CALL &&
11472 + !strcmp(insn->call_dest->name,
11473 + "__ubsan_handle_builtin_unreachable"));
11474 +}
11475 +
11476 +static bool ignore_unreachable_insn(struct instruction *insn)
11477 +{
11478 + int i;
11479 +
11480 + if (insn->ignore || insn->type == INSN_NOP)
11481 + return true;
11482 +
11483 + /*
11484 + * Ignore any unused exceptions. This can happen when a whitelisted
11485 + * function has an exception table entry.
11486 + *
11487 + * Also ignore alternative replacement instructions. This can happen
11488 + * when a whitelisted function uses one of the ALTERNATIVE macros.
11489 + */
11490 + if (!strcmp(insn->sec->name, ".fixup") ||
11491 + !strcmp(insn->sec->name, ".altinstr_replacement") ||
11492 + !strcmp(insn->sec->name, ".altinstr_aux"))
11493 + return true;
11494 +
11495 + /*
11496 + * Check if this (or a subsequent) instruction is related to
11497 + * CONFIG_UBSAN or CONFIG_KASAN.
11498 + *
11499 + * End the search at 5 instructions to avoid going into the weeds.
11500 + */
11501 + if (!insn->func)
11502 + return false;
11503 + for (i = 0; i < 5; i++) {
11504 +
11505 + if (is_kasan_insn(insn) || is_ubsan_insn(insn))
11506 + return true;
11507 +
11508 + if (insn->type == INSN_JUMP_UNCONDITIONAL) {
11509 + if (insn->jump_dest &&
11510 + insn->jump_dest->func == insn->func) {
11511 + insn = insn->jump_dest;
11512 + continue;
11513 + }
11514 +
11515 + break;
11516 + }
11517 +
11518 + if (insn->offset + insn->len >= insn->func->offset + insn->func->len)
11519 + break;
11520 +
11521 + insn = list_next_entry(insn, list);
11522 + }
11523 +
11524 + return false;
11525 +}
11526 +
11527 +static int validate_functions(struct objtool_file *file)
11528 +{
11529 + struct section *sec;
11530 + struct symbol *func;
11531 + struct instruction *insn;
11532 + struct insn_state state;
11533 + int ret, warnings = 0;
11534 +
11535 + clear_insn_state(&state);
11536 +
11537 + state.cfa = initial_func_cfi.cfa;
11538 + memcpy(&state.regs, &initial_func_cfi.regs,
11539 + CFI_NUM_REGS * sizeof(struct cfi_reg));
11540 + state.stack_size = initial_func_cfi.cfa.offset;
11541 +
11542 + for_each_sec(file, sec) {
11543 + list_for_each_entry(func, &sec->symbol_list, list) {
11544 + if (func->type != STT_FUNC || func->pfunc != func)
11545 + continue;
11546 +
11547 + insn = find_insn(file, sec, func->offset);
11548 + if (!insn || insn->ignore)
11549 + continue;
11550 +
11551 + ret = validate_branch(file, insn, state);
11552 + warnings += ret;
11553 + }
11554 + }
11555 +
11556 + return warnings;
11557 +}
11558 +
11559 +static int validate_reachable_instructions(struct objtool_file *file)
11560 +{
11561 + struct instruction *insn;
11562 +
11563 + if (file->ignore_unreachables)
11564 + return 0;
11565 +
11566 + for_each_insn(file, insn) {
11567 + if (insn->visited || ignore_unreachable_insn(insn))
11568 + continue;
11569 +
11570 + WARN_FUNC("unreachable instruction", insn->sec, insn->offset);
11571 + return 1;
11572 + }
11573 +
11574 + return 0;
11575 +}
11576 +
11577 +static void cleanup(struct objtool_file *file)
11578 +{
11579 + struct instruction *insn, *tmpinsn;
11580 + struct alternative *alt, *tmpalt;
11581 +
11582 + list_for_each_entry_safe(insn, tmpinsn, &file->insn_list, list) {
11583 + list_for_each_entry_safe(alt, tmpalt, &insn->alts, list) {
11584 + list_del(&alt->list);
11585 + free(alt);
11586 + }
11587 + list_del(&insn->list);
11588 + hash_del(&insn->hash);
11589 + free(insn);
11590 + }
11591 + elf_close(file->elf);
11592 +}
11593 +
11594 +int check(const char *_objname, bool orc)
11595 +{
11596 + struct objtool_file file;
11597 + int ret, warnings = 0;
11598 +
11599 + objname = _objname;
11600 +
11601 + file.elf = elf_open(objname, orc ? O_RDWR : O_RDONLY);
11602 + if (!file.elf)
11603 + return 1;
11604 +
11605 + INIT_LIST_HEAD(&file.insn_list);
11606 + hash_init(file.insn_hash);
11607 + file.whitelist = find_section_by_name(file.elf, ".discard.func_stack_frame_non_standard");
11608 + file.rodata = find_section_by_name(file.elf, ".rodata");
11609 + file.c_file = find_section_by_name(file.elf, ".comment");
11610 + file.ignore_unreachables = no_unreachable;
11611 + file.hints = false;
11612 +
11613 + arch_initial_func_cfi_state(&initial_func_cfi);
11614 +
11615 + ret = decode_sections(&file);
11616 + if (ret < 0)
11617 + goto out;
11618 + warnings += ret;
11619 +
11620 + if (list_empty(&file.insn_list))
11621 + goto out;
11622 +
11623 + if (retpoline) {
11624 + ret = validate_retpoline(&file);
11625 + if (ret < 0)
11626 + return ret;
11627 + warnings += ret;
11628 + }
11629 +
11630 + ret = validate_functions(&file);
11631 + if (ret < 0)
11632 + goto out;
11633 + warnings += ret;
11634 +
11635 + ret = validate_unwind_hints(&file);
11636 + if (ret < 0)
11637 + goto out;
11638 + warnings += ret;
11639 +
11640 + if (!warnings) {
11641 + ret = validate_reachable_instructions(&file);
11642 + if (ret < 0)
11643 + goto out;
11644 + warnings += ret;
11645 + }
11646 +
11647 + if (orc) {
11648 + ret = create_orc(&file);
11649 + if (ret < 0)
11650 + goto out;
11651 +
11652 + ret = create_orc_sections(&file);
11653 + if (ret < 0)
11654 + goto out;
11655 +
11656 + ret = elf_write(file.elf);
11657 + if (ret < 0)
11658 + goto out;
11659 + }
11660 +
11661 +out:
11662 + cleanup(&file);
11663 +
11664 + /* ignore warnings for now until we get all the code cleaned up */
11665 + if (ret || warnings)
11666 + return 0;
11667 + return 0;
11668 +}
11669 diff --git a/tools/objtool/check.h b/tools/objtool/check.h
11670 new file mode 100644
11671 index 000000000000..c6b68fcb926f
11672 --- /dev/null
11673 +++ b/tools/objtool/check.h
11674 @@ -0,0 +1,82 @@
11675 +/*
11676 + * Copyright (C) 2017 Josh Poimboeuf <jpoimboe@redhat.com>
11677 + *
11678 + * This program is free software; you can redistribute it and/or
11679 + * modify it under the terms of the GNU General Public License
11680 + * as published by the Free Software Foundation; either version 2
11681 + * of the License, or (at your option) any later version.
11682 + *
11683 + * This program is distributed in the hope that it will be useful,
11684 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
11685 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11686 + * GNU General Public License for more details.
11687 + *
11688 + * You should have received a copy of the GNU General Public License
11689 + * along with this program; if not, see <http://www.gnu.org/licenses/>.
11690 + */
11691 +
11692 +#ifndef _CHECK_H
11693 +#define _CHECK_H
11694 +
11695 +#include <stdbool.h>
11696 +#include "elf.h"
11697 +#include "cfi.h"
11698 +#include "arch.h"
11699 +#include "orc.h"
11700 +#include <linux/hashtable.h>
11701 +
11702 +struct insn_state {
11703 + struct cfi_reg cfa;
11704 + struct cfi_reg regs[CFI_NUM_REGS];
11705 + int stack_size;
11706 + unsigned char type;
11707 + bool bp_scratch;
11708 + bool drap;
11709 + int drap_reg, drap_offset;
11710 + struct cfi_reg vals[CFI_NUM_REGS];
11711 +};
11712 +
11713 +struct instruction {
11714 + struct list_head list;
11715 + struct hlist_node hash;
11716 + struct section *sec;
11717 + unsigned long offset;
11718 + unsigned int len;
11719 + unsigned char type;
11720 + unsigned long immediate;
11721 + bool alt_group, visited, dead_end, ignore, hint, save, restore, ignore_alts;
11722 + bool retpoline_safe;
11723 + struct symbol *call_dest;
11724 + struct instruction *jump_dest;
11725 + struct instruction *first_jump_src;
11726 + struct list_head alts;
11727 + struct symbol *func;
11728 + struct stack_op stack_op;
11729 + struct insn_state state;
11730 + struct orc_entry orc;
11731 +};
11732 +
11733 +struct objtool_file {
11734 + struct elf *elf;
11735 + struct list_head insn_list;
11736 + DECLARE_HASHTABLE(insn_hash, 16);
11737 + struct section *rodata, *whitelist;
11738 + bool ignore_unreachables, c_file, hints;
11739 +};
11740 +
11741 +int check(const char *objname, bool orc);
11742 +
11743 +struct instruction *find_insn(struct objtool_file *file,
11744 + struct section *sec, unsigned long offset);
11745 +
11746 +#define for_each_insn(file, insn) \
11747 + list_for_each_entry(insn, &file->insn_list, list)
11748 +
11749 +#define sec_for_each_insn(file, sec, insn) \
11750 + for (insn = find_insn(file, sec, 0); \
11751 + insn && &insn->list != &file->insn_list && \
11752 + insn->sec == sec; \
11753 + insn = list_next_entry(insn, list))
11754 +
11755 +
11756 +#endif /* _CHECK_H */
11757 diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c
11758 index faacf0c89976..4e60e105583e 100644
11759 --- a/tools/objtool/elf.c
11760 +++ b/tools/objtool/elf.c
11761 @@ -31,13 +31,6 @@
11762 #include "elf.h"
11763 #include "warn.h"
11764
11765 -/*
11766 - * Fallback for systems without this "read, mmaping if possible" cmd.
11767 - */
11768 -#ifndef ELF_C_READ_MMAP
11769 -#define ELF_C_READ_MMAP ELF_C_READ
11770 -#endif
11771 -
11772 struct section *find_section_by_name(struct elf *elf, const char *name)
11773 {
11774 struct section *sec;
11775 @@ -86,6 +79,19 @@ struct symbol *find_symbol_by_offset(struct section *sec, unsigned long offset)
11776 return NULL;
11777 }
11778
11779 +struct symbol *find_symbol_by_name(struct elf *elf, const char *name)
11780 +{
11781 + struct section *sec;
11782 + struct symbol *sym;
11783 +
11784 + list_for_each_entry(sec, &elf->sections, list)
11785 + list_for_each_entry(sym, &sec->symbol_list, list)
11786 + if (!strcmp(sym->name, name))
11787 + return sym;
11788 +
11789 + return NULL;
11790 +}
11791 +
11792 struct symbol *find_symbol_containing(struct section *sec, unsigned long offset)
11793 {
11794 struct symbol *sym;
11795 @@ -140,12 +146,12 @@ static int read_sections(struct elf *elf)
11796 int i;
11797
11798 if (elf_getshdrnum(elf->elf, &sections_nr)) {
11799 - perror("elf_getshdrnum");
11800 + WARN_ELF("elf_getshdrnum");
11801 return -1;
11802 }
11803
11804 if (elf_getshdrstrndx(elf->elf, &shstrndx)) {
11805 - perror("elf_getshdrstrndx");
11806 + WARN_ELF("elf_getshdrstrndx");
11807 return -1;
11808 }
11809
11810 @@ -166,37 +172,37 @@ static int read_sections(struct elf *elf)
11811
11812 s = elf_getscn(elf->elf, i);
11813 if (!s) {
11814 - perror("elf_getscn");
11815 + WARN_ELF("elf_getscn");
11816 return -1;
11817 }
11818
11819 sec->idx = elf_ndxscn(s);
11820
11821 if (!gelf_getshdr(s, &sec->sh)) {
11822 - perror("gelf_getshdr");
11823 + WARN_ELF("gelf_getshdr");
11824 return -1;
11825 }
11826
11827 sec->name = elf_strptr(elf->elf, shstrndx, sec->sh.sh_name);
11828 if (!sec->name) {
11829 - perror("elf_strptr");
11830 + WARN_ELF("elf_strptr");
11831 return -1;
11832 }
11833
11834 - sec->elf_data = elf_getdata(s, NULL);
11835 - if (!sec->elf_data) {
11836 - perror("elf_getdata");
11837 - return -1;
11838 - }
11839 -
11840 - if (sec->elf_data->d_off != 0 ||
11841 - sec->elf_data->d_size != sec->sh.sh_size) {
11842 - WARN("unexpected data attributes for %s", sec->name);
11843 - return -1;
11844 + if (sec->sh.sh_size != 0) {
11845 + sec->data = elf_getdata(s, NULL);
11846 + if (!sec->data) {
11847 + WARN_ELF("elf_getdata");
11848 + return -1;
11849 + }
11850 + if (sec->data->d_off != 0 ||
11851 + sec->data->d_size != sec->sh.sh_size) {
11852 + WARN("unexpected data attributes for %s",
11853 + sec->name);
11854 + return -1;
11855 + }
11856 }
11857 -
11858 - sec->data = (unsigned long)sec->elf_data->d_buf;
11859 - sec->len = sec->elf_data->d_size;
11860 + sec->len = sec->sh.sh_size;
11861 }
11862
11863 /* sanity check, one more call to elf_nextscn() should return NULL */
11864 @@ -210,10 +216,11 @@ static int read_sections(struct elf *elf)
11865
11866 static int read_symbols(struct elf *elf)
11867 {
11868 - struct section *symtab;
11869 - struct symbol *sym;
11870 + struct section *symtab, *sec;
11871 + struct symbol *sym, *pfunc;
11872 struct list_head *entry, *tmp;
11873 int symbols_nr, i;
11874 + char *coldstr;
11875
11876 symtab = find_section_by_name(elf, ".symtab");
11877 if (!symtab) {
11878 @@ -233,15 +240,15 @@ static int read_symbols(struct elf *elf)
11879
11880 sym->idx = i;
11881
11882 - if (!gelf_getsym(symtab->elf_data, i, &sym->sym)) {
11883 - perror("gelf_getsym");
11884 + if (!gelf_getsym(symtab->data, i, &sym->sym)) {
11885 + WARN_ELF("gelf_getsym");
11886 goto err;
11887 }
11888
11889 sym->name = elf_strptr(elf->elf, symtab->sh.sh_link,
11890 sym->sym.st_name);
11891 if (!sym->name) {
11892 - perror("elf_strptr");
11893 + WARN_ELF("elf_strptr");
11894 goto err;
11895 }
11896
11897 @@ -288,6 +295,30 @@ static int read_symbols(struct elf *elf)
11898 hash_add(sym->sec->symbol_hash, &sym->hash, sym->idx);
11899 }
11900
11901 + /* Create parent/child links for any cold subfunctions */
11902 + list_for_each_entry(sec, &elf->sections, list) {
11903 + list_for_each_entry(sym, &sec->symbol_list, list) {
11904 + if (sym->type != STT_FUNC)
11905 + continue;
11906 + sym->pfunc = sym->cfunc = sym;
11907 + coldstr = strstr(sym->name, ".cold.");
11908 + if (coldstr) {
11909 + coldstr[0] = '\0';
11910 + pfunc = find_symbol_by_name(elf, sym->name);
11911 + coldstr[0] = '.';
11912 +
11913 + if (!pfunc) {
11914 + WARN("%s(): can't find parent function",
11915 + sym->name);
11916 + goto err;
11917 + }
11918 +
11919 + sym->pfunc = pfunc;
11920 + pfunc->cfunc = sym;
11921 + }
11922 + }
11923 + }
11924 +
11925 return 0;
11926
11927 err:
11928 @@ -323,8 +354,8 @@ static int read_relas(struct elf *elf)
11929 }
11930 memset(rela, 0, sizeof(*rela));
11931
11932 - if (!gelf_getrela(sec->elf_data, i, &rela->rela)) {
11933 - perror("gelf_getrela");
11934 + if (!gelf_getrela(sec->data, i, &rela->rela)) {
11935 + WARN_ELF("gelf_getrela");
11936 return -1;
11937 }
11938
11939 @@ -348,9 +379,10 @@ static int read_relas(struct elf *elf)
11940 return 0;
11941 }
11942
11943 -struct elf *elf_open(const char *name)
11944 +struct elf *elf_open(const char *name, int flags)
11945 {
11946 struct elf *elf;
11947 + Elf_Cmd cmd;
11948
11949 elf_version(EV_CURRENT);
11950
11951 @@ -363,27 +395,28 @@ struct elf *elf_open(const char *name)
11952
11953 INIT_LIST_HEAD(&elf->sections);
11954
11955 - elf->name = strdup(name);
11956 - if (!elf->name) {
11957 - perror("strdup");
11958 - goto err;
11959 - }
11960 -
11961 - elf->fd = open(name, O_RDONLY);
11962 + elf->fd = open(name, flags);
11963 if (elf->fd == -1) {
11964 fprintf(stderr, "objtool: Can't open '%s': %s\n",
11965 name, strerror(errno));
11966 goto err;
11967 }
11968
11969 - elf->elf = elf_begin(elf->fd, ELF_C_READ_MMAP, NULL);
11970 + if ((flags & O_ACCMODE) == O_RDONLY)
11971 + cmd = ELF_C_READ_MMAP;
11972 + else if ((flags & O_ACCMODE) == O_RDWR)
11973 + cmd = ELF_C_RDWR;
11974 + else /* O_WRONLY */
11975 + cmd = ELF_C_WRITE;
11976 +
11977 + elf->elf = elf_begin(elf->fd, cmd, NULL);
11978 if (!elf->elf) {
11979 - perror("elf_begin");
11980 + WARN_ELF("elf_begin");
11981 goto err;
11982 }
11983
11984 if (!gelf_getehdr(elf->elf, &elf->ehdr)) {
11985 - perror("gelf_getehdr");
11986 + WARN_ELF("gelf_getehdr");
11987 goto err;
11988 }
11989
11990 @@ -403,12 +436,212 @@ struct elf *elf_open(const char *name)
11991 return NULL;
11992 }
11993
11994 +struct section *elf_create_section(struct elf *elf, const char *name,
11995 + size_t entsize, int nr)
11996 +{
11997 + struct section *sec, *shstrtab;
11998 + size_t size = entsize * nr;
11999 + struct Elf_Scn *s;
12000 + Elf_Data *data;
12001 +
12002 + sec = malloc(sizeof(*sec));
12003 + if (!sec) {
12004 + perror("malloc");
12005 + return NULL;
12006 + }
12007 + memset(sec, 0, sizeof(*sec));
12008 +
12009 + INIT_LIST_HEAD(&sec->symbol_list);
12010 + INIT_LIST_HEAD(&sec->rela_list);
12011 + hash_init(sec->rela_hash);
12012 + hash_init(sec->symbol_hash);
12013 +
12014 + list_add_tail(&sec->list, &elf->sections);
12015 +
12016 + s = elf_newscn(elf->elf);
12017 + if (!s) {
12018 + WARN_ELF("elf_newscn");
12019 + return NULL;
12020 + }
12021 +
12022 + sec->name = strdup(name);
12023 + if (!sec->name) {
12024 + perror("strdup");
12025 + return NULL;
12026 + }
12027 +
12028 + sec->idx = elf_ndxscn(s);
12029 + sec->len = size;
12030 + sec->changed = true;
12031 +
12032 + sec->data = elf_newdata(s);
12033 + if (!sec->data) {
12034 + WARN_ELF("elf_newdata");
12035 + return NULL;
12036 + }
12037 +
12038 + sec->data->d_size = size;
12039 + sec->data->d_align = 1;
12040 +
12041 + if (size) {
12042 + sec->data->d_buf = malloc(size);
12043 + if (!sec->data->d_buf) {
12044 + perror("malloc");
12045 + return NULL;
12046 + }
12047 + memset(sec->data->d_buf, 0, size);
12048 + }
12049 +
12050 + if (!gelf_getshdr(s, &sec->sh)) {
12051 + WARN_ELF("gelf_getshdr");
12052 + return NULL;
12053 + }
12054 +
12055 + sec->sh.sh_size = size;
12056 + sec->sh.sh_entsize = entsize;
12057 + sec->sh.sh_type = SHT_PROGBITS;
12058 + sec->sh.sh_addralign = 1;
12059 + sec->sh.sh_flags = SHF_ALLOC;
12060 +
12061 +
12062 + /* Add section name to .shstrtab */
12063 + shstrtab = find_section_by_name(elf, ".shstrtab");
12064 + if (!shstrtab) {
12065 + WARN("can't find .shstrtab section");
12066 + return NULL;
12067 + }
12068 +
12069 + s = elf_getscn(elf->elf, shstrtab->idx);
12070 + if (!s) {
12071 + WARN_ELF("elf_getscn");
12072 + return NULL;
12073 + }
12074 +
12075 + data = elf_newdata(s);
12076 + if (!data) {
12077 + WARN_ELF("elf_newdata");
12078 + return NULL;
12079 + }
12080 +
12081 + data->d_buf = sec->name;
12082 + data->d_size = strlen(name) + 1;
12083 + data->d_align = 1;
12084 +
12085 + sec->sh.sh_name = shstrtab->len;
12086 +
12087 + shstrtab->len += strlen(name) + 1;
12088 + shstrtab->changed = true;
12089 +
12090 + return sec;
12091 +}
12092 +
12093 +struct section *elf_create_rela_section(struct elf *elf, struct section *base)
12094 +{
12095 + char *relaname;
12096 + struct section *sec;
12097 +
12098 + relaname = malloc(strlen(base->name) + strlen(".rela") + 1);
12099 + if (!relaname) {
12100 + perror("malloc");
12101 + return NULL;
12102 + }
12103 + strcpy(relaname, ".rela");
12104 + strcat(relaname, base->name);
12105 +
12106 + sec = elf_create_section(elf, relaname, sizeof(GElf_Rela), 0);
12107 + free(relaname);
12108 + if (!sec)
12109 + return NULL;
12110 +
12111 + base->rela = sec;
12112 + sec->base = base;
12113 +
12114 + sec->sh.sh_type = SHT_RELA;
12115 + sec->sh.sh_addralign = 8;
12116 + sec->sh.sh_link = find_section_by_name(elf, ".symtab")->idx;
12117 + sec->sh.sh_info = base->idx;
12118 + sec->sh.sh_flags = SHF_INFO_LINK;
12119 +
12120 + return sec;
12121 +}
12122 +
12123 +int elf_rebuild_rela_section(struct section *sec)
12124 +{
12125 + struct rela *rela;
12126 + int nr, idx = 0, size;
12127 + GElf_Rela *relas;
12128 +
12129 + nr = 0;
12130 + list_for_each_entry(rela, &sec->rela_list, list)
12131 + nr++;
12132 +
12133 + size = nr * sizeof(*relas);
12134 + relas = malloc(size);
12135 + if (!relas) {
12136 + perror("malloc");
12137 + return -1;
12138 + }
12139 +
12140 + sec->data->d_buf = relas;
12141 + sec->data->d_size = size;
12142 +
12143 + sec->sh.sh_size = size;
12144 +
12145 + idx = 0;
12146 + list_for_each_entry(rela, &sec->rela_list, list) {
12147 + relas[idx].r_offset = rela->offset;
12148 + relas[idx].r_addend = rela->addend;
12149 + relas[idx].r_info = GELF_R_INFO(rela->sym->idx, rela->type);
12150 + idx++;
12151 + }
12152 +
12153 + return 0;
12154 +}
12155 +
12156 +int elf_write(struct elf *elf)
12157 +{
12158 + struct section *sec;
12159 + Elf_Scn *s;
12160 +
12161 + /* Update section headers for changed sections: */
12162 + list_for_each_entry(sec, &elf->sections, list) {
12163 + if (sec->changed) {
12164 + s = elf_getscn(elf->elf, sec->idx);
12165 + if (!s) {
12166 + WARN_ELF("elf_getscn");
12167 + return -1;
12168 + }
12169 + if (!gelf_update_shdr(s, &sec->sh)) {
12170 + WARN_ELF("gelf_update_shdr");
12171 + return -1;
12172 + }
12173 + }
12174 + }
12175 +
12176 + /* Make sure the new section header entries get updated properly. */
12177 + elf_flagelf(elf->elf, ELF_C_SET, ELF_F_DIRTY);
12178 +
12179 + /* Write all changes to the file. */
12180 + if (elf_update(elf->elf, ELF_C_WRITE) < 0) {
12181 + WARN_ELF("elf_update");
12182 + return -1;
12183 + }
12184 +
12185 + return 0;
12186 +}
12187 +
12188 void elf_close(struct elf *elf)
12189 {
12190 struct section *sec, *tmpsec;
12191 struct symbol *sym, *tmpsym;
12192 struct rela *rela, *tmprela;
12193
12194 + if (elf->elf)
12195 + elf_end(elf->elf);
12196 +
12197 + if (elf->fd > 0)
12198 + close(elf->fd);
12199 +
12200 list_for_each_entry_safe(sec, tmpsec, &elf->sections, list) {
12201 list_for_each_entry_safe(sym, tmpsym, &sec->symbol_list, list) {
12202 list_del(&sym->list);
12203 @@ -423,11 +656,6 @@ void elf_close(struct elf *elf)
12204 list_del(&sec->list);
12205 free(sec);
12206 }
12207 - if (elf->name)
12208 - free(elf->name);
12209 - if (elf->fd > 0)
12210 - close(elf->fd);
12211 - if (elf->elf)
12212 - elf_end(elf->elf);
12213 +
12214 free(elf);
12215 }
12216 diff --git a/tools/objtool/elf.h b/tools/objtool/elf.h
12217 index 731973e1a3f5..de5cd2ddded9 100644
12218 --- a/tools/objtool/elf.h
12219 +++ b/tools/objtool/elf.h
12220 @@ -28,6 +28,13 @@
12221 # define elf_getshdrstrndx elf_getshstrndx
12222 #endif
12223
12224 +/*
12225 + * Fallback for systems without this "read, mmaping if possible" cmd.
12226 + */
12227 +#ifndef ELF_C_READ_MMAP
12228 +#define ELF_C_READ_MMAP ELF_C_READ
12229 +#endif
12230 +
12231 struct section {
12232 struct list_head list;
12233 GElf_Shdr sh;
12234 @@ -37,11 +44,11 @@ struct section {
12235 DECLARE_HASHTABLE(rela_hash, 16);
12236 struct section *base, *rela;
12237 struct symbol *sym;
12238 - Elf_Data *elf_data;
12239 + Elf_Data *data;
12240 char *name;
12241 int idx;
12242 - unsigned long data;
12243 unsigned int len;
12244 + bool changed, text;
12245 };
12246
12247 struct symbol {
12248 @@ -54,6 +61,7 @@ struct symbol {
12249 unsigned char bind, type;
12250 unsigned long offset;
12251 unsigned int len;
12252 + struct symbol *pfunc, *cfunc;
12253 };
12254
12255 struct rela {
12256 @@ -76,16 +84,23 @@ struct elf {
12257 };
12258
12259
12260 -struct elf *elf_open(const char *name);
12261 +struct elf *elf_open(const char *name, int flags);
12262 struct section *find_section_by_name(struct elf *elf, const char *name);
12263 struct symbol *find_symbol_by_offset(struct section *sec, unsigned long offset);
12264 +struct symbol *find_symbol_by_name(struct elf *elf, const char *name);
12265 struct symbol *find_symbol_containing(struct section *sec, unsigned long offset);
12266 struct rela *find_rela_by_dest(struct section *sec, unsigned long offset);
12267 struct rela *find_rela_by_dest_range(struct section *sec, unsigned long offset,
12268 unsigned int len);
12269 struct symbol *find_containing_func(struct section *sec, unsigned long offset);
12270 +struct section *elf_create_section(struct elf *elf, const char *name, size_t
12271 + entsize, int nr);
12272 +struct section *elf_create_rela_section(struct elf *elf, struct section *base);
12273 +int elf_rebuild_rela_section(struct section *sec);
12274 +int elf_write(struct elf *elf);
12275 void elf_close(struct elf *elf);
12276
12277 -
12278 +#define for_each_sec(file, sec) \
12279 + list_for_each_entry(sec, &file->elf->sections, list)
12280
12281 #endif /* _OBJTOOL_ELF_H */
12282 diff --git a/tools/objtool/objtool.c b/tools/objtool/objtool.c
12283 index 46c326db4f46..07f329919828 100644
12284 --- a/tools/objtool/objtool.c
12285 +++ b/tools/objtool/objtool.c
12286 @@ -31,11 +31,10 @@
12287 #include <stdlib.h>
12288 #include <subcmd/exec-cmd.h>
12289 #include <subcmd/pager.h>
12290 +#include <linux/kernel.h>
12291
12292 #include "builtin.h"
12293
12294 -#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
12295 -
12296 struct cmd_struct {
12297 const char *name;
12298 int (*fn)(int, const char **);
12299 @@ -43,10 +42,11 @@ struct cmd_struct {
12300 };
12301
12302 static const char objtool_usage_string[] =
12303 - "objtool [OPTIONS] COMMAND [ARGS]";
12304 + "objtool COMMAND [ARGS]";
12305
12306 static struct cmd_struct objtool_cmds[] = {
12307 {"check", cmd_check, "Perform stack metadata validation on an object file" },
12308 + {"orc", cmd_orc, "Generate in-place ORC unwind tables for an object file" },
12309 };
12310
12311 bool help;
12312 @@ -70,7 +70,7 @@ static void cmd_usage(void)
12313
12314 printf("\n");
12315
12316 - exit(1);
12317 + exit(129);
12318 }
12319
12320 static void handle_options(int *argc, const char ***argv)
12321 @@ -86,9 +86,7 @@ static void handle_options(int *argc, const char ***argv)
12322 break;
12323 } else {
12324 fprintf(stderr, "Unknown option: %s\n", cmd);
12325 - fprintf(stderr, "\n Usage: %s\n",
12326 - objtool_usage_string);
12327 - exit(1);
12328 + cmd_usage();
12329 }
12330
12331 (*argv)++;
12332 diff --git a/tools/objtool/orc.h b/tools/objtool/orc.h
12333 new file mode 100644
12334 index 000000000000..b0e92a6d0903
12335 --- /dev/null
12336 +++ b/tools/objtool/orc.h
12337 @@ -0,0 +1,30 @@
12338 +/*
12339 + * Copyright (C) 2017 Josh Poimboeuf <jpoimboe@redhat.com>
12340 + *
12341 + * This program is free software; you can redistribute it and/or
12342 + * modify it under the terms of the GNU General Public License
12343 + * as published by the Free Software Foundation; either version 2
12344 + * of the License, or (at your option) any later version.
12345 + *
12346 + * This program is distributed in the hope that it will be useful,
12347 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
12348 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12349 + * GNU General Public License for more details.
12350 + *
12351 + * You should have received a copy of the GNU General Public License
12352 + * along with this program; if not, see <http://www.gnu.org/licenses/>.
12353 + */
12354 +
12355 +#ifndef _ORC_H
12356 +#define _ORC_H
12357 +
12358 +#include <asm/orc_types.h>
12359 +
12360 +struct objtool_file;
12361 +
12362 +int create_orc(struct objtool_file *file);
12363 +int create_orc_sections(struct objtool_file *file);
12364 +
12365 +int orc_dump(const char *objname);
12366 +
12367 +#endif /* _ORC_H */
12368 diff --git a/tools/objtool/orc_dump.c b/tools/objtool/orc_dump.c
12369 new file mode 100644
12370 index 000000000000..c3343820916a
12371 --- /dev/null
12372 +++ b/tools/objtool/orc_dump.c
12373 @@ -0,0 +1,213 @@
12374 +/*
12375 + * Copyright (C) 2017 Josh Poimboeuf <jpoimboe@redhat.com>
12376 + *
12377 + * This program is free software; you can redistribute it and/or
12378 + * modify it under the terms of the GNU General Public License
12379 + * as published by the Free Software Foundation; either version 2
12380 + * of the License, or (at your option) any later version.
12381 + *
12382 + * This program is distributed in the hope that it will be useful,
12383 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
12384 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12385 + * GNU General Public License for more details.
12386 + *
12387 + * You should have received a copy of the GNU General Public License
12388 + * along with this program; if not, see <http://www.gnu.org/licenses/>.
12389 + */
12390 +
12391 +#include <unistd.h>
12392 +#include "orc.h"
12393 +#include "warn.h"
12394 +
12395 +static const char *reg_name(unsigned int reg)
12396 +{
12397 + switch (reg) {
12398 + case ORC_REG_PREV_SP:
12399 + return "prevsp";
12400 + case ORC_REG_DX:
12401 + return "dx";
12402 + case ORC_REG_DI:
12403 + return "di";
12404 + case ORC_REG_BP:
12405 + return "bp";
12406 + case ORC_REG_SP:
12407 + return "sp";
12408 + case ORC_REG_R10:
12409 + return "r10";
12410 + case ORC_REG_R13:
12411 + return "r13";
12412 + case ORC_REG_BP_INDIRECT:
12413 + return "bp(ind)";
12414 + case ORC_REG_SP_INDIRECT:
12415 + return "sp(ind)";
12416 + default:
12417 + return "?";
12418 + }
12419 +}
12420 +
12421 +static const char *orc_type_name(unsigned int type)
12422 +{
12423 + switch (type) {
12424 + case ORC_TYPE_CALL:
12425 + return "call";
12426 + case ORC_TYPE_REGS:
12427 + return "regs";
12428 + case ORC_TYPE_REGS_IRET:
12429 + return "iret";
12430 + default:
12431 + return "?";
12432 + }
12433 +}
12434 +
12435 +static void print_reg(unsigned int reg, int offset)
12436 +{
12437 + if (reg == ORC_REG_BP_INDIRECT)
12438 + printf("(bp%+d)", offset);
12439 + else if (reg == ORC_REG_SP_INDIRECT)
12440 + printf("(sp%+d)", offset);
12441 + else if (reg == ORC_REG_UNDEFINED)
12442 + printf("(und)");
12443 + else
12444 + printf("%s%+d", reg_name(reg), offset);
12445 +}
12446 +
12447 +int orc_dump(const char *_objname)
12448 +{
12449 + int fd, nr_entries, i, *orc_ip = NULL, orc_size = 0;
12450 + struct orc_entry *orc = NULL;
12451 + char *name;
12452 + size_t nr_sections;
12453 + Elf64_Addr orc_ip_addr = 0;
12454 + size_t shstrtab_idx;
12455 + Elf *elf;
12456 + Elf_Scn *scn;
12457 + GElf_Shdr sh;
12458 + GElf_Rela rela;
12459 + GElf_Sym sym;
12460 + Elf_Data *data, *symtab = NULL, *rela_orc_ip = NULL;
12461 +
12462 +
12463 + objname = _objname;
12464 +
12465 + elf_version(EV_CURRENT);
12466 +
12467 + fd = open(objname, O_RDONLY);
12468 + if (fd == -1) {
12469 + perror("open");
12470 + return -1;
12471 + }
12472 +
12473 + elf = elf_begin(fd, ELF_C_READ_MMAP, NULL);
12474 + if (!elf) {
12475 + WARN_ELF("elf_begin");
12476 + return -1;
12477 + }
12478 +
12479 + if (elf_getshdrnum(elf, &nr_sections)) {
12480 + WARN_ELF("elf_getshdrnum");
12481 + return -1;
12482 + }
12483 +
12484 + if (elf_getshdrstrndx(elf, &shstrtab_idx)) {
12485 + WARN_ELF("elf_getshdrstrndx");
12486 + return -1;
12487 + }
12488 +
12489 + for (i = 0; i < nr_sections; i++) {
12490 + scn = elf_getscn(elf, i);
12491 + if (!scn) {
12492 + WARN_ELF("elf_getscn");
12493 + return -1;
12494 + }
12495 +
12496 + if (!gelf_getshdr(scn, &sh)) {
12497 + WARN_ELF("gelf_getshdr");
12498 + return -1;
12499 + }
12500 +
12501 + name = elf_strptr(elf, shstrtab_idx, sh.sh_name);
12502 + if (!name) {
12503 + WARN_ELF("elf_strptr");
12504 + return -1;
12505 + }
12506 +
12507 + data = elf_getdata(scn, NULL);
12508 + if (!data) {
12509 + WARN_ELF("elf_getdata");
12510 + return -1;
12511 + }
12512 +
12513 + if (!strcmp(name, ".symtab")) {
12514 + symtab = data;
12515 + } else if (!strcmp(name, ".orc_unwind")) {
12516 + orc = data->d_buf;
12517 + orc_size = sh.sh_size;
12518 + } else if (!strcmp(name, ".orc_unwind_ip")) {
12519 + orc_ip = data->d_buf;
12520 + orc_ip_addr = sh.sh_addr;
12521 + } else if (!strcmp(name, ".rela.orc_unwind_ip")) {
12522 + rela_orc_ip = data;
12523 + }
12524 + }
12525 +
12526 + if (!symtab || !orc || !orc_ip)
12527 + return 0;
12528 +
12529 + if (orc_size % sizeof(*orc) != 0) {
12530 + WARN("bad .orc_unwind section size");
12531 + return -1;
12532 + }
12533 +
12534 + nr_entries = orc_size / sizeof(*orc);
12535 + for (i = 0; i < nr_entries; i++) {
12536 + if (rela_orc_ip) {
12537 + if (!gelf_getrela(rela_orc_ip, i, &rela)) {
12538 + WARN_ELF("gelf_getrela");
12539 + return -1;
12540 + }
12541 +
12542 + if (!gelf_getsym(symtab, GELF_R_SYM(rela.r_info), &sym)) {
12543 + WARN_ELF("gelf_getsym");
12544 + return -1;
12545 + }
12546 +
12547 + scn = elf_getscn(elf, sym.st_shndx);
12548 + if (!scn) {
12549 + WARN_ELF("elf_getscn");
12550 + return -1;
12551 + }
12552 +
12553 + if (!gelf_getshdr(scn, &sh)) {
12554 + WARN_ELF("gelf_getshdr");
12555 + return -1;
12556 + }
12557 +
12558 + name = elf_strptr(elf, shstrtab_idx, sh.sh_name);
12559 + if (!name || !*name) {
12560 + WARN_ELF("elf_strptr");
12561 + return -1;
12562 + }
12563 +
12564 + printf("%s+%llx:", name, (unsigned long long)rela.r_addend);
12565 +
12566 + } else {
12567 + printf("%llx:", (unsigned long long)(orc_ip_addr + (i * sizeof(int)) + orc_ip[i]));
12568 + }
12569 +
12570 +
12571 + printf(" sp:");
12572 +
12573 + print_reg(orc[i].sp_reg, orc[i].sp_offset);
12574 +
12575 + printf(" bp:");
12576 +
12577 + print_reg(orc[i].bp_reg, orc[i].bp_offset);
12578 +
12579 + printf(" type:%s\n", orc_type_name(orc[i].type));
12580 + }
12581 +
12582 + elf_end(elf);
12583 + close(fd);
12584 +
12585 + return 0;
12586 +}
12587 diff --git a/tools/objtool/orc_gen.c b/tools/objtool/orc_gen.c
12588 new file mode 100644
12589 index 000000000000..18384d9be4e1
12590 --- /dev/null
12591 +++ b/tools/objtool/orc_gen.c
12592 @@ -0,0 +1,221 @@
12593 +/*
12594 + * Copyright (C) 2017 Josh Poimboeuf <jpoimboe@redhat.com>
12595 + *
12596 + * This program is free software; you can redistribute it and/or
12597 + * modify it under the terms of the GNU General Public License
12598 + * as published by the Free Software Foundation; either version 2
12599 + * of the License, or (at your option) any later version.
12600 + *
12601 + * This program is distributed in the hope that it will be useful,
12602 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
12603 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12604 + * GNU General Public License for more details.
12605 + *
12606 + * You should have received a copy of the GNU General Public License
12607 + * along with this program; if not, see <http://www.gnu.org/licenses/>.
12608 + */
12609 +
12610 +#include <stdlib.h>
12611 +#include <string.h>
12612 +
12613 +#include "orc.h"
12614 +#include "check.h"
12615 +#include "warn.h"
12616 +
12617 +int create_orc(struct objtool_file *file)
12618 +{
12619 + struct instruction *insn;
12620 +
12621 + for_each_insn(file, insn) {
12622 + struct orc_entry *orc = &insn->orc;
12623 + struct cfi_reg *cfa = &insn->state.cfa;
12624 + struct cfi_reg *bp = &insn->state.regs[CFI_BP];
12625 +
12626 + if (cfa->base == CFI_UNDEFINED) {
12627 + orc->sp_reg = ORC_REG_UNDEFINED;
12628 + continue;
12629 + }
12630 +
12631 + switch (cfa->base) {
12632 + case CFI_SP:
12633 + orc->sp_reg = ORC_REG_SP;
12634 + break;
12635 + case CFI_SP_INDIRECT:
12636 + orc->sp_reg = ORC_REG_SP_INDIRECT;
12637 + break;
12638 + case CFI_BP:
12639 + orc->sp_reg = ORC_REG_BP;
12640 + break;
12641 + case CFI_BP_INDIRECT:
12642 + orc->sp_reg = ORC_REG_BP_INDIRECT;
12643 + break;
12644 + case CFI_R10:
12645 + orc->sp_reg = ORC_REG_R10;
12646 + break;
12647 + case CFI_R13:
12648 + orc->sp_reg = ORC_REG_R13;
12649 + break;
12650 + case CFI_DI:
12651 + orc->sp_reg = ORC_REG_DI;
12652 + break;
12653 + case CFI_DX:
12654 + orc->sp_reg = ORC_REG_DX;
12655 + break;
12656 + default:
12657 + WARN_FUNC("unknown CFA base reg %d",
12658 + insn->sec, insn->offset, cfa->base);
12659 + return -1;
12660 + }
12661 +
12662 + switch(bp->base) {
12663 + case CFI_UNDEFINED:
12664 + orc->bp_reg = ORC_REG_UNDEFINED;
12665 + break;
12666 + case CFI_CFA:
12667 + orc->bp_reg = ORC_REG_PREV_SP;
12668 + break;
12669 + case CFI_BP:
12670 + orc->bp_reg = ORC_REG_BP;
12671 + break;
12672 + default:
12673 + WARN_FUNC("unknown BP base reg %d",
12674 + insn->sec, insn->offset, bp->base);
12675 + return -1;
12676 + }
12677 +
12678 + orc->sp_offset = cfa->offset;
12679 + orc->bp_offset = bp->offset;
12680 + orc->type = insn->state.type;
12681 + }
12682 +
12683 + return 0;
12684 +}
12685 +
12686 +static int create_orc_entry(struct section *u_sec, struct section *ip_relasec,
12687 + unsigned int idx, struct section *insn_sec,
12688 + unsigned long insn_off, struct orc_entry *o)
12689 +{
12690 + struct orc_entry *orc;
12691 + struct rela *rela;
12692 +
12693 + if (!insn_sec->sym) {
12694 + WARN("missing symbol for section %s", insn_sec->name);
12695 + return -1;
12696 + }
12697 +
12698 + /* populate ORC data */
12699 + orc = (struct orc_entry *)u_sec->data->d_buf + idx;
12700 + memcpy(orc, o, sizeof(*orc));
12701 +
12702 + /* populate rela for ip */
12703 + rela = malloc(sizeof(*rela));
12704 + if (!rela) {
12705 + perror("malloc");
12706 + return -1;
12707 + }
12708 + memset(rela, 0, sizeof(*rela));
12709 +
12710 + rela->sym = insn_sec->sym;
12711 + rela->addend = insn_off;
12712 + rela->type = R_X86_64_PC32;
12713 + rela->offset = idx * sizeof(int);
12714 +
12715 + list_add_tail(&rela->list, &ip_relasec->rela_list);
12716 + hash_add(ip_relasec->rela_hash, &rela->hash, rela->offset);
12717 +
12718 + return 0;
12719 +}
12720 +
12721 +int create_orc_sections(struct objtool_file *file)
12722 +{
12723 + struct instruction *insn, *prev_insn;
12724 + struct section *sec, *u_sec, *ip_relasec;
12725 + unsigned int idx;
12726 +
12727 + struct orc_entry empty = {
12728 + .sp_reg = ORC_REG_UNDEFINED,
12729 + .bp_reg = ORC_REG_UNDEFINED,
12730 + .type = ORC_TYPE_CALL,
12731 + };
12732 +
12733 + sec = find_section_by_name(file->elf, ".orc_unwind");
12734 + if (sec) {
12735 + WARN("file already has .orc_unwind section, skipping");
12736 + return -1;
12737 + }
12738 +
12739 + /* count the number of needed orcs */
12740 + idx = 0;
12741 + for_each_sec(file, sec) {
12742 + if (!sec->text)
12743 + continue;
12744 +
12745 + prev_insn = NULL;
12746 + sec_for_each_insn(file, sec, insn) {
12747 + if (!prev_insn ||
12748 + memcmp(&insn->orc, &prev_insn->orc,
12749 + sizeof(struct orc_entry))) {
12750 + idx++;
12751 + }
12752 + prev_insn = insn;
12753 + }
12754 +
12755 + /* section terminator */
12756 + if (prev_insn)
12757 + idx++;
12758 + }
12759 + if (!idx)
12760 + return -1;
12761 +
12762 +
12763 + /* create .orc_unwind_ip and .rela.orc_unwind_ip sections */
12764 + sec = elf_create_section(file->elf, ".orc_unwind_ip", sizeof(int), idx);
12765 + if (!sec)
12766 + return -1;
12767 +
12768 + ip_relasec = elf_create_rela_section(file->elf, sec);
12769 + if (!ip_relasec)
12770 + return -1;
12771 +
12772 + /* create .orc_unwind section */
12773 + u_sec = elf_create_section(file->elf, ".orc_unwind",
12774 + sizeof(struct orc_entry), idx);
12775 +
12776 + /* populate sections */
12777 + idx = 0;
12778 + for_each_sec(file, sec) {
12779 + if (!sec->text)
12780 + continue;
12781 +
12782 + prev_insn = NULL;
12783 + sec_for_each_insn(file, sec, insn) {
12784 + if (!prev_insn || memcmp(&insn->orc, &prev_insn->orc,
12785 + sizeof(struct orc_entry))) {
12786 +
12787 + if (create_orc_entry(u_sec, ip_relasec, idx,
12788 + insn->sec, insn->offset,
12789 + &insn->orc))
12790 + return -1;
12791 +
12792 + idx++;
12793 + }
12794 + prev_insn = insn;
12795 + }
12796 +
12797 + /* section terminator */
12798 + if (prev_insn) {
12799 + if (create_orc_entry(u_sec, ip_relasec, idx,
12800 + prev_insn->sec,
12801 + prev_insn->offset + prev_insn->len,
12802 + &empty))
12803 + return -1;
12804 +
12805 + idx++;
12806 + }
12807 + }
12808 +
12809 + if (elf_rebuild_rela_section(ip_relasec))
12810 + return -1;
12811 +
12812 + return 0;
12813 +}
12814 diff --git a/tools/objtool/special.c b/tools/objtool/special.c
12815 index bff8abb3a4aa..84f001d52322 100644
12816 --- a/tools/objtool/special.c
12817 +++ b/tools/objtool/special.c
12818 @@ -91,16 +91,16 @@ static int get_alt_entry(struct elf *elf, struct special_entry *entry,
12819 alt->jump_or_nop = entry->jump_or_nop;
12820
12821 if (alt->group) {
12822 - alt->orig_len = *(unsigned char *)(sec->data + offset +
12823 + alt->orig_len = *(unsigned char *)(sec->data->d_buf + offset +
12824 entry->orig_len);
12825 - alt->new_len = *(unsigned char *)(sec->data + offset +
12826 + alt->new_len = *(unsigned char *)(sec->data->d_buf + offset +
12827 entry->new_len);
12828 }
12829
12830 if (entry->feature) {
12831 unsigned short feature;
12832
12833 - feature = *(unsigned short *)(sec->data + offset +
12834 + feature = *(unsigned short *)(sec->data->d_buf + offset +
12835 entry->feature);
12836
12837 /*
12838 diff --git a/tools/objtool/sync-check.sh b/tools/objtool/sync-check.sh
12839 new file mode 100755
12840 index 000000000000..1470e74e9d66
12841 --- /dev/null
12842 +++ b/tools/objtool/sync-check.sh
12843 @@ -0,0 +1,29 @@
12844 +#!/bin/sh
12845 +# SPDX-License-Identifier: GPL-2.0
12846 +
12847 +FILES='
12848 +arch/x86/lib/insn.c
12849 +arch/x86/lib/inat.c
12850 +arch/x86/lib/x86-opcode-map.txt
12851 +arch/x86/tools/gen-insn-attr-x86.awk
12852 +arch/x86/include/asm/insn.h
12853 +arch/x86/include/asm/inat.h
12854 +arch/x86/include/asm/inat_types.h
12855 +arch/x86/include/asm/orc_types.h
12856 +'
12857 +
12858 +check()
12859 +{
12860 + local file=$1
12861 +
12862 + diff $file ../../$file > /dev/null ||
12863 + echo "Warning: synced file at 'tools/objtool/$file' differs from latest kernel version at '$file'"
12864 +}
12865 +
12866 +if [ ! -d ../../kernel ] || [ ! -d ../../tools ] || [ ! -d ../objtool ]; then
12867 + exit 0
12868 +fi
12869 +
12870 +for i in $FILES; do
12871 + check $i
12872 +done
12873 diff --git a/tools/objtool/warn.h b/tools/objtool/warn.h
12874 index ac7e07523e84..afd9f7a05f6d 100644
12875 --- a/tools/objtool/warn.h
12876 +++ b/tools/objtool/warn.h
12877 @@ -18,6 +18,13 @@
12878 #ifndef _WARN_H
12879 #define _WARN_H
12880
12881 +#include <stdlib.h>
12882 +#include <string.h>
12883 +#include <sys/types.h>
12884 +#include <sys/stat.h>
12885 +#include <fcntl.h>
12886 +#include "elf.h"
12887 +
12888 extern const char *objname;
12889
12890 static inline char *offstr(struct section *sec, unsigned long offset)
12891 @@ -57,4 +64,7 @@ static inline char *offstr(struct section *sec, unsigned long offset)
12892 free(_str); \
12893 })
12894
12895 +#define WARN_ELF(format, ...) \
12896 + WARN(format ": %s", ##__VA_ARGS__, elf_errmsg(-1))
12897 +
12898 #endif /* _WARN_H */
12899 diff --git a/tools/perf/MANIFEST b/tools/perf/MANIFEST
12900 index 0bda2cca2b3a..a4f98e131819 100644
12901 --- a/tools/perf/MANIFEST
12902 +++ b/tools/perf/MANIFEST
12903 @@ -51,6 +51,7 @@ tools/include/asm-generic/bitops/arch_hweight.h
12904 tools/include/asm-generic/bitops/atomic.h
12905 tools/include/asm-generic/bitops/const_hweight.h
12906 tools/include/asm-generic/bitops/__ffs.h
12907 +tools/include/asm-generic/bitops/__ffz.h
12908 tools/include/asm-generic/bitops/__fls.h
12909 tools/include/asm-generic/bitops/find.h
12910 tools/include/asm-generic/bitops/fls64.h
12911 @@ -60,7 +61,9 @@ tools/include/asm-generic/bitops.h
12912 tools/include/linux/atomic.h
12913 tools/include/linux/bitops.h
12914 tools/include/linux/compiler.h
12915 +tools/include/linux/compiler-gcc.h
12916 tools/include/linux/coresight-pmu.h
12917 +tools/include/linux/bug.h
12918 tools/include/linux/filter.h
12919 tools/include/linux/hash.h
12920 tools/include/linux/kernel.h
12921 @@ -70,12 +73,15 @@ tools/include/uapi/asm-generic/mman-common.h
12922 tools/include/uapi/asm-generic/mman.h
12923 tools/include/uapi/linux/bpf.h
12924 tools/include/uapi/linux/bpf_common.h
12925 +tools/include/uapi/linux/fcntl.h
12926 tools/include/uapi/linux/hw_breakpoint.h
12927 tools/include/uapi/linux/mman.h
12928 tools/include/uapi/linux/perf_event.h
12929 +tools/include/uapi/linux/stat.h
12930 tools/include/linux/poison.h
12931 tools/include/linux/rbtree.h
12932 tools/include/linux/rbtree_augmented.h
12933 +tools/include/linux/refcount.h
12934 tools/include/linux/string.h
12935 tools/include/linux/stringify.h
12936 tools/include/linux/types.h
12937 diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
12938 index 2b92ffef554b..ad3726c5754d 100644
12939 --- a/tools/perf/Makefile.perf
12940 +++ b/tools/perf/Makefile.perf
12941 @@ -177,6 +177,36 @@ ifeq ($(filter-out $(NON_CONFIG_TARGETS),$(MAKECMDGOALS)),)
12942 endif
12943 endif
12944
12945 +# The fixdep build - we force fixdep tool to be built as
12946 +# the first target in the separate make session not to be
12947 +# disturbed by any parallel make jobs. Once fixdep is done
12948 +# we issue the requested build with FIXDEP=1 variable.
12949 +#
12950 +# The fixdep build is disabled for $(NON_CONFIG_TARGETS)
12951 +# targets, because it's not necessary.
12952 +
12953 +ifdef FIXDEP
12954 + force_fixdep := 0
12955 +else
12956 + force_fixdep := $(config)
12957 +endif
12958 +
12959 +export srctree OUTPUT RM CC CXX LD AR CFLAGS CXXFLAGS V BISON FLEX AWK
12960 +export HOSTCC HOSTLD HOSTAR
12961 +
12962 +include $(srctree)/tools/build/Makefile.include
12963 +
12964 +ifeq ($(force_fixdep),1)
12965 +goals := $(filter-out all sub-make, $(MAKECMDGOALS))
12966 +
12967 +$(goals) all: sub-make
12968 +
12969 +sub-make: fixdep
12970 + @./check-headers.sh
12971 + $(Q)$(MAKE) FIXDEP=1 -f Makefile.perf $(goals)
12972 +
12973 +else # force_fixdep
12974 +
12975 # Set FEATURE_TESTS to 'all' so all possible feature checkers are executed.
12976 # Without this setting the output feature dump file misses some features, for
12977 # example, liberty. Select all checkers so we won't get an incomplete feature
12978 @@ -348,10 +378,6 @@ strip: $(PROGRAMS) $(OUTPUT)perf
12979
12980 PERF_IN := $(OUTPUT)perf-in.o
12981
12982 -export srctree OUTPUT RM CC LD AR CFLAGS V BISON FLEX AWK
12983 -export HOSTCC HOSTLD HOSTAR
12984 -include $(srctree)/tools/build/Makefile.include
12985 -
12986 JEVENTS := $(OUTPUT)pmu-events/jevents
12987 JEVENTS_IN := $(OUTPUT)pmu-events/jevents-in.o
12988
12989 @@ -362,99 +388,6 @@ export JEVENTS
12990 build := -f $(srctree)/tools/build/Makefile.build dir=. obj
12991
12992 $(PERF_IN): prepare FORCE
12993 - @(test -f ../../include/uapi/linux/perf_event.h && ( \
12994 - (diff -B ../include/uapi/linux/perf_event.h ../../include/uapi/linux/perf_event.h >/dev/null) \
12995 - || echo "Warning: tools/include/uapi/linux/perf_event.h differs from kernel" >&2 )) || true
12996 - @(test -f ../../include/linux/hash.h && ( \
12997 - (diff -B ../include/linux/hash.h ../../include/linux/hash.h >/dev/null) \
12998 - || echo "Warning: tools/include/linux/hash.h differs from kernel" >&2 )) || true
12999 - @(test -f ../../include/uapi/linux/hw_breakpoint.h && ( \
13000 - (diff -B ../include/uapi/linux/hw_breakpoint.h ../../include/uapi/linux/hw_breakpoint.h >/dev/null) \
13001 - || echo "Warning: tools/include/uapi/linux/hw_breakpoint.h differs from kernel" >&2 )) || true
13002 - @(test -f ../../arch/x86/include/asm/disabled-features.h && ( \
13003 - (diff -B ../arch/x86/include/asm/disabled-features.h ../../arch/x86/include/asm/disabled-features.h >/dev/null) \
13004 - || echo "Warning: tools/arch/x86/include/asm/disabled-features.h differs from kernel" >&2 )) || true
13005 - @(test -f ../../arch/x86/include/asm/required-features.h && ( \
13006 - (diff -B ../arch/x86/include/asm/required-features.h ../../arch/x86/include/asm/required-features.h >/dev/null) \
13007 - || echo "Warning: tools/arch/x86/include/asm/required-features.h differs from kernel" >&2 )) || true
13008 - @(test -f ../../arch/x86/include/asm/cpufeatures.h && ( \
13009 - (diff -B ../arch/x86/include/asm/cpufeatures.h ../../arch/x86/include/asm/cpufeatures.h >/dev/null) \
13010 - || echo "Warning: tools/arch/x86/include/asm/cpufeatures.h differs from kernel" >&2 )) || true
13011 - @(test -f ../../arch/x86/lib/memcpy_64.S && ( \
13012 - (diff -B ../arch/x86/lib/memcpy_64.S ../../arch/x86/lib/memcpy_64.S >/dev/null) \
13013 - || echo "Warning: tools/arch/x86/lib/memcpy_64.S differs from kernel" >&2 )) || true
13014 - @(test -f ../../arch/x86/lib/memset_64.S && ( \
13015 - (diff -B ../arch/x86/lib/memset_64.S ../../arch/x86/lib/memset_64.S >/dev/null) \
13016 - || echo "Warning: tools/arch/x86/lib/memset_64.S differs from kernel" >&2 )) || true
13017 - @(test -f ../../arch/arm/include/uapi/asm/perf_regs.h && ( \
13018 - (diff -B ../arch/arm/include/uapi/asm/perf_regs.h ../../arch/arm/include/uapi/asm/perf_regs.h >/dev/null) \
13019 - || echo "Warning: tools/arch/arm/include/uapi/asm/perf_regs.h differs from kernel" >&2 )) || true
13020 - @(test -f ../../arch/arm64/include/uapi/asm/perf_regs.h && ( \
13021 - (diff -B ../arch/arm64/include/uapi/asm/perf_regs.h ../../arch/arm64/include/uapi/asm/perf_regs.h >/dev/null) \
13022 - || echo "Warning: tools/arch/arm64/include/uapi/asm/perf_regs.h differs from kernel" >&2 )) || true
13023 - @(test -f ../../arch/powerpc/include/uapi/asm/perf_regs.h && ( \
13024 - (diff -B ../arch/powerpc/include/uapi/asm/perf_regs.h ../../arch/powerpc/include/uapi/asm/perf_regs.h >/dev/null) \
13025 - || echo "Warning: tools/arch/powerpc/include/uapi/asm/perf_regs.h differs from kernel" >&2 )) || true
13026 - @(test -f ../../arch/x86/include/uapi/asm/perf_regs.h && ( \
13027 - (diff -B ../arch/x86/include/uapi/asm/perf_regs.h ../../arch/x86/include/uapi/asm/perf_regs.h >/dev/null) \
13028 - || echo "Warning: tools/arch/x86/include/uapi/asm/perf_regs.h differs from kernel" >&2 )) || true
13029 - @(test -f ../../arch/x86/include/uapi/asm/kvm.h && ( \
13030 - (diff -B ../arch/x86/include/uapi/asm/kvm.h ../../arch/x86/include/uapi/asm/kvm.h >/dev/null) \
13031 - || echo "Warning: tools/arch/x86/include/uapi/asm/kvm.h differs from kernel" >&2 )) || true
13032 - @(test -f ../../arch/x86/include/uapi/asm/kvm_perf.h && ( \
13033 - (diff -B ../arch/x86/include/uapi/asm/kvm_perf.h ../../arch/x86/include/uapi/asm/kvm_perf.h >/dev/null) \
13034 - || echo "Warning: tools/arch/x86/include/uapi/asm/kvm_perf.h differs from kernel" >&2 )) || true
13035 - @(test -f ../../arch/x86/include/uapi/asm/svm.h && ( \
13036 - (diff -B ../arch/x86/include/uapi/asm/svm.h ../../arch/x86/include/uapi/asm/svm.h >/dev/null) \
13037 - || echo "Warning: tools/arch/x86/include/uapi/asm/svm.h differs from kernel" >&2 )) || true
13038 - @(test -f ../../arch/x86/include/uapi/asm/vmx.h && ( \
13039 - (diff -B ../arch/x86/include/uapi/asm/vmx.h ../../arch/x86/include/uapi/asm/vmx.h >/dev/null) \
13040 - || echo "Warning: tools/arch/x86/include/uapi/asm/vmx.h differs from kernel" >&2 )) || true
13041 - @(test -f ../../arch/powerpc/include/uapi/asm/kvm.h && ( \
13042 - (diff -B ../arch/powerpc/include/uapi/asm/kvm.h ../../arch/powerpc/include/uapi/asm/kvm.h >/dev/null) \
13043 - || echo "Warning: tools/arch/powerpc/include/uapi/asm/kvm.h differs from kernel" >&2 )) || true
13044 - @(test -f ../../arch/s390/include/uapi/asm/kvm.h && ( \
13045 - (diff -B ../arch/s390/include/uapi/asm/kvm.h ../../arch/s390/include/uapi/asm/kvm.h >/dev/null) \
13046 - || echo "Warning: tools/arch/s390/include/uapi/asm/kvm.h differs from kernel" >&2 )) || true
13047 - @(test -f ../../arch/s390/include/uapi/asm/kvm_perf.h && ( \
13048 - (diff -B ../arch/s390/include/uapi/asm/kvm_perf.h ../../arch/s390/include/uapi/asm/kvm_perf.h >/dev/null) \
13049 - || echo "Warning: tools/arch/s390/include/uapi/asm/kvm_perf.h differs from kernel" >&2 )) || true
13050 - @(test -f ../../arch/s390/include/uapi/asm/sie.h && ( \
13051 - (diff -B ../arch/s390/include/uapi/asm/sie.h ../../arch/s390/include/uapi/asm/sie.h >/dev/null) \
13052 - || echo "Warning: tools/arch/s390/include/uapi/asm/sie.h differs from kernel" >&2 )) || true
13053 - @(test -f ../../arch/arm/include/uapi/asm/kvm.h && ( \
13054 - (diff -B ../arch/arm/include/uapi/asm/kvm.h ../../arch/arm/include/uapi/asm/kvm.h >/dev/null) \
13055 - || echo "Warning: tools/arch/arm/include/uapi/asm/kvm.h differs from kernel" >&2 )) || true
13056 - @(test -f ../../arch/arm64/include/uapi/asm/kvm.h && ( \
13057 - (diff -B ../arch/arm64/include/uapi/asm/kvm.h ../../arch/arm64/include/uapi/asm/kvm.h >/dev/null) \
13058 - || echo "Warning: tools/arch/arm64/include/uapi/asm/kvm.h differs from kernel" >&2 )) || true
13059 - @(test -f ../../include/asm-generic/bitops/arch_hweight.h && ( \
13060 - (diff -B ../include/asm-generic/bitops/arch_hweight.h ../../include/asm-generic/bitops/arch_hweight.h >/dev/null) \
13061 - || echo "Warning: tools/include/asm-generic/bitops/arch_hweight.h differs from kernel" >&2 )) || true
13062 - @(test -f ../../include/asm-generic/bitops/const_hweight.h && ( \
13063 - (diff -B ../include/asm-generic/bitops/const_hweight.h ../../include/asm-generic/bitops/const_hweight.h >/dev/null) \
13064 - || echo "Warning: tools/include/asm-generic/bitops/const_hweight.h differs from kernel" >&2 )) || true
13065 - @(test -f ../../include/asm-generic/bitops/__fls.h && ( \
13066 - (diff -B ../include/asm-generic/bitops/__fls.h ../../include/asm-generic/bitops/__fls.h >/dev/null) \
13067 - || echo "Warning: tools/include/asm-generic/bitops/__fls.h differs from kernel" >&2 )) || true
13068 - @(test -f ../../include/asm-generic/bitops/fls.h && ( \
13069 - (diff -B ../include/asm-generic/bitops/fls.h ../../include/asm-generic/bitops/fls.h >/dev/null) \
13070 - || echo "Warning: tools/include/asm-generic/bitops/fls.h differs from kernel" >&2 )) || true
13071 - @(test -f ../../include/asm-generic/bitops/fls64.h && ( \
13072 - (diff -B ../include/asm-generic/bitops/fls64.h ../../include/asm-generic/bitops/fls64.h >/dev/null) \
13073 - || echo "Warning: tools/include/asm-generic/bitops/fls64.h differs from kernel" >&2 )) || true
13074 - @(test -f ../../include/linux/coresight-pmu.h && ( \
13075 - (diff -B ../include/linux/coresight-pmu.h ../../include/linux/coresight-pmu.h >/dev/null) \
13076 - || echo "Warning: tools/include/linux/coresight-pmu.h differs from kernel" >&2 )) || true
13077 - @(test -f ../../include/uapi/asm-generic/mman-common.h && ( \
13078 - (diff -B ../include/uapi/asm-generic/mman-common.h ../../include/uapi/asm-generic/mman-common.h >/dev/null) \
13079 - || echo "Warning: tools/include/uapi/asm-generic/mman-common.h differs from kernel" >&2 )) || true
13080 - @(test -f ../../include/uapi/asm-generic/mman.h && ( \
13081 - (diff -B -I "^#include <\(uapi/\)*asm-generic/mman-common.h>$$" ../include/uapi/asm-generic/mman.h ../../include/uapi/asm-generic/mman.h >/dev/null) \
13082 - || echo "Warning: tools/include/uapi/asm-generic/mman.h differs from kernel" >&2 )) || true
13083 - @(test -f ../../include/uapi/linux/mman.h && ( \
13084 - (diff -B -I "^#include <\(uapi/\)*asm/mman.h>$$" ../include/uapi/linux/mman.h ../../include/uapi/linux/mman.h >/dev/null) \
13085 - || echo "Warning: tools/include/uapi/linux/mman.h differs from kernel" >&2 )) || true
13086 $(Q)$(MAKE) $(build)=perf
13087
13088 $(JEVENTS_IN): FORCE
13089 @@ -470,7 +403,7 @@ $(OUTPUT)perf: $(PERFLIBS) $(PERF_IN) $(PMU_EVENTS_IN) $(LIBTRACEEVENT_DYNAMIC_L
13090 $(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) $(LIBTRACEEVENT_DYNAMIC_LIST_LDFLAGS) \
13091 $(PERF_IN) $(PMU_EVENTS_IN) $(LIBS) -o $@
13092
13093 -$(GTK_IN): fixdep FORCE
13094 +$(GTK_IN): FORCE
13095 $(Q)$(MAKE) $(build)=gtk
13096
13097 $(OUTPUT)libperf-gtk.so: $(GTK_IN) $(PERFLIBS)
13098 @@ -515,7 +448,7 @@ endif
13099 __build-dir = $(subst $(OUTPUT),,$(dir $@))
13100 build-dir = $(if $(__build-dir),$(__build-dir),.)
13101
13102 -prepare: $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)common-cmds.h fixdep archheaders
13103 +prepare: $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)common-cmds.h archheaders
13104
13105 $(OUTPUT)%.o: %.c prepare FORCE
13106 $(Q)$(MAKE) -f $(srctree)/tools/build/Makefile.build dir=$(build-dir) $@
13107 @@ -555,7 +488,7 @@ $(patsubst perf-%,%.o,$(PROGRAMS)): $(wildcard */*.h)
13108
13109 LIBPERF_IN := $(OUTPUT)libperf-in.o
13110
13111 -$(LIBPERF_IN): prepare fixdep FORCE
13112 +$(LIBPERF_IN): prepare FORCE
13113 $(Q)$(MAKE) $(build)=libperf
13114
13115 $(LIB_FILE): $(LIBPERF_IN)
13116 @@ -563,10 +496,10 @@ $(LIB_FILE): $(LIBPERF_IN)
13117
13118 LIBTRACEEVENT_FLAGS += plugin_dir=$(plugindir_SQ)
13119
13120 -$(LIBTRACEEVENT): fixdep FORCE
13121 +$(LIBTRACEEVENT): FORCE
13122 $(Q)$(MAKE) -C $(TRACE_EVENT_DIR) $(LIBTRACEEVENT_FLAGS) O=$(OUTPUT) $(OUTPUT)libtraceevent.a
13123
13124 -libtraceevent_plugins: fixdep FORCE
13125 +libtraceevent_plugins: FORCE
13126 $(Q)$(MAKE) -C $(TRACE_EVENT_DIR) $(LIBTRACEEVENT_FLAGS) O=$(OUTPUT) plugins
13127
13128 $(LIBTRACEEVENT_DYNAMIC_LIST): libtraceevent_plugins
13129 @@ -579,21 +512,21 @@ $(LIBTRACEEVENT)-clean:
13130 install-traceevent-plugins: libtraceevent_plugins
13131 $(Q)$(MAKE) -C $(TRACE_EVENT_DIR) $(LIBTRACEEVENT_FLAGS) O=$(OUTPUT) install_plugins
13132
13133 -$(LIBAPI): fixdep FORCE
13134 +$(LIBAPI): FORCE
13135 $(Q)$(MAKE) -C $(LIB_DIR) O=$(OUTPUT) $(OUTPUT)libapi.a
13136
13137 $(LIBAPI)-clean:
13138 $(call QUIET_CLEAN, libapi)
13139 $(Q)$(MAKE) -C $(LIB_DIR) O=$(OUTPUT) clean >/dev/null
13140
13141 -$(LIBBPF): fixdep FORCE
13142 +$(LIBBPF): FORCE
13143 $(Q)$(MAKE) -C $(BPF_DIR) O=$(OUTPUT) $(OUTPUT)libbpf.a FEATURES_DUMP=$(FEATURE_DUMP_EXPORT)
13144
13145 $(LIBBPF)-clean:
13146 $(call QUIET_CLEAN, libbpf)
13147 $(Q)$(MAKE) -C $(BPF_DIR) O=$(OUTPUT) clean >/dev/null
13148
13149 -$(LIBSUBCMD): fixdep FORCE
13150 +$(LIBSUBCMD): FORCE
13151 $(Q)$(MAKE) -C $(SUBCMD_DIR) O=$(OUTPUT) $(OUTPUT)libsubcmd.a
13152
13153 $(LIBSUBCMD)-clean:
13154 @@ -790,3 +723,4 @@ FORCE:
13155 .PHONY: $(GIT-HEAD-PHONY) TAGS tags cscope FORCE prepare
13156 .PHONY: libtraceevent_plugins archheaders
13157
13158 +endif # force_fixdep
13159 diff --git a/tools/perf/arch/x86/entry/syscalls/syscall_64.tbl b/tools/perf/arch/x86/entry/syscalls/syscall_64.tbl
13160 index 555263e385c9..e93ef0b38db8 100644
13161 --- a/tools/perf/arch/x86/entry/syscalls/syscall_64.tbl
13162 +++ b/tools/perf/arch/x86/entry/syscalls/syscall_64.tbl
13163 @@ -335,6 +335,9 @@
13164 326 common copy_file_range sys_copy_file_range
13165 327 64 preadv2 sys_preadv2
13166 328 64 pwritev2 sys_pwritev2
13167 +329 common pkey_mprotect sys_pkey_mprotect
13168 +330 common pkey_alloc sys_pkey_alloc
13169 +331 common pkey_free sys_pkey_free
13170
13171 #
13172 # x32-specific system call numbers start at 512 to avoid cache impact
13173 @@ -374,5 +377,5 @@
13174 543 x32 io_setup compat_sys_io_setup
13175 544 x32 io_submit compat_sys_io_submit
13176 545 x32 execveat compat_sys_execveat/ptregs
13177 -534 x32 preadv2 compat_sys_preadv2
13178 -535 x32 pwritev2 compat_sys_pwritev2
13179 +546 x32 preadv2 compat_sys_preadv64v2
13180 +547 x32 pwritev2 compat_sys_pwritev64v2
13181 diff --git a/tools/perf/check-headers.sh b/tools/perf/check-headers.sh
13182 new file mode 100755
13183 index 000000000000..83fe2202382e
13184 --- /dev/null
13185 +++ b/tools/perf/check-headers.sh
13186 @@ -0,0 +1,61 @@
13187 +#!/bin/sh
13188 +
13189 +HEADERS='
13190 +include/uapi/linux/fcntl.h
13191 +include/uapi/linux/perf_event.h
13192 +include/uapi/linux/stat.h
13193 +include/linux/hash.h
13194 +include/uapi/linux/hw_breakpoint.h
13195 +arch/x86/include/asm/disabled-features.h
13196 +arch/x86/include/asm/required-features.h
13197 +arch/x86/include/asm/cpufeatures.h
13198 +arch/arm/include/uapi/asm/perf_regs.h
13199 +arch/arm64/include/uapi/asm/perf_regs.h
13200 +arch/powerpc/include/uapi/asm/perf_regs.h
13201 +arch/x86/include/uapi/asm/perf_regs.h
13202 +arch/x86/include/uapi/asm/kvm.h
13203 +arch/x86/include/uapi/asm/kvm_perf.h
13204 +arch/x86/include/uapi/asm/svm.h
13205 +arch/x86/include/uapi/asm/vmx.h
13206 +arch/powerpc/include/uapi/asm/kvm.h
13207 +arch/s390/include/uapi/asm/kvm.h
13208 +arch/s390/include/uapi/asm/kvm_perf.h
13209 +arch/s390/include/uapi/asm/sie.h
13210 +arch/arm/include/uapi/asm/kvm.h
13211 +arch/arm64/include/uapi/asm/kvm.h
13212 +include/asm-generic/bitops/arch_hweight.h
13213 +include/asm-generic/bitops/const_hweight.h
13214 +include/asm-generic/bitops/__fls.h
13215 +include/asm-generic/bitops/fls.h
13216 +include/asm-generic/bitops/fls64.h
13217 +include/linux/coresight-pmu.h
13218 +include/uapi/asm-generic/mman-common.h
13219 +'
13220 +
13221 +check () {
13222 + file=$1
13223 + opts=
13224 +
13225 + shift
13226 + while [ -n "$*" ]; do
13227 + opts="$opts \"$1\""
13228 + shift
13229 + done
13230 +
13231 + cmd="diff $opts ../$file ../../$file > /dev/null"
13232 +
13233 + test -f ../../$file &&
13234 + eval $cmd || echo "Warning: $file differs from kernel" >&2
13235 +}
13236 +
13237 +
13238 +# simple diff check
13239 +for i in $HEADERS; do
13240 + check $i -B
13241 +done
13242 +
13243 +# diff with extra ignore lines
13244 +check arch/x86/lib/memcpy_64.S -B -I "^EXPORT_SYMBOL" -I "^#include <asm/export.h>"
13245 +check arch/x86/lib/memset_64.S -B -I "^EXPORT_SYMBOL" -I "^#include <asm/export.h>"
13246 +check include/uapi/asm-generic/mman.h -B -I "^#include <\(uapi/\)*asm-generic/mman-common.h>"
13247 +check include/uapi/linux/mman.h -B -I "^#include <\(uapi/\)*asm/mman.h>"
13248 diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h
13249 index 43899e0d6fa1..e72d370889f8 100644
13250 --- a/tools/perf/util/util.h
13251 +++ b/tools/perf/util/util.h
13252 @@ -23,8 +23,6 @@
13253 #endif
13254 #endif
13255
13256 -#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
13257 -
13258 #ifdef __GNUC__
13259 #define TYPEOF(x) (__typeof__(x))
13260 #else