Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

x86/unwind: Add the ORC unwinder

Add the new ORC unwinder which is enabled by CONFIG_ORC_UNWINDER=y.
It plugs into the existing x86 unwinder framework.

It relies on objtool to generate the needed .orc_unwind and
.orc_unwind_ip sections.

For more details on why ORC is used instead of DWARF, see
Documentation/x86/orc-unwinder.txt - but the short version is
that it's a simplified, fundamentally more robust debugninfo
data structure, which also allows up to two orders of magnitude
faster lookups than the DWARF unwinder - which matters to
profiling workloads like perf.

Thanks to Andy Lutomirski for the performance improvement ideas:
splitting the ORC unwind table into two parallel arrays and creating a
fast lookup table to search a subset of the unwind table.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: Denys Vlasenko <dvlasenk@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Jiri Slaby <jslaby@suse.cz>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: live-patching@vger.kernel.org
Link: http://lkml.kernel.org/r/0a6cbfb40f8da99b7a45a1a8302dc6aef16ec812.1500938583.git.jpoimboe@redhat.com
[ Extended the changelog. ]
Signed-off-by: Ingo Molnar <mingo@kernel.org>

authored by

Josh Poimboeuf and committed by
Ingo Molnar
ee9f8fce 1ee6f00d

+980 -67
+179
Documentation/x86/orc-unwinder.txt
··· 1 + ORC unwinder 2 + ============ 3 + 4 + Overview 5 + -------- 6 + 7 + The kernel CONFIG_ORC_UNWINDER option enables the ORC unwinder, which is 8 + similar in concept to a DWARF unwinder. The difference is that the 9 + format of the ORC data is much simpler than DWARF, which in turn allows 10 + the ORC unwinder to be much simpler and faster. 11 + 12 + The ORC data consists of unwind tables which are generated by objtool. 13 + They contain out-of-band data which is used by the in-kernel ORC 14 + unwinder. Objtool generates the ORC data by first doing compile-time 15 + stack metadata validation (CONFIG_STACK_VALIDATION). After analyzing 16 + all the code paths of a .o file, it determines information about the 17 + stack state at each instruction address in the file and outputs that 18 + information to the .orc_unwind and .orc_unwind_ip sections. 19 + 20 + The per-object ORC sections are combined at link time and are sorted and 21 + post-processed at boot time. The unwinder uses the resulting data to 22 + correlate instruction addresses with their stack states at run time. 23 + 24 + 25 + ORC vs frame pointers 26 + --------------------- 27 + 28 + With frame pointers enabled, GCC adds instrumentation code to every 29 + function in the kernel. The kernel's .text size increases by about 30 + 3.2%, resulting in a broad kernel-wide slowdown. Measurements by Mel 31 + Gorman [1] have shown a slowdown of 5-10% for some workloads. 32 + 33 + In contrast, the ORC unwinder has no effect on text size or runtime 34 + performance, because the debuginfo is out of band. So if you disable 35 + frame pointers and enable the ORC unwinder, you get a nice performance 36 + improvement across the board, and still have reliable stack traces. 37 + 38 + Ingo Molnar says: 39 + 40 + "Note that it's not just a performance improvement, but also an 41 + instruction cache locality improvement: 3.2% .text savings almost 42 + directly transform into a similarly sized reduction in cache 43 + footprint. That can transform to even higher speedups for workloads 44 + whose cache locality is borderline." 45 + 46 + Another benefit of ORC compared to frame pointers is that it can 47 + reliably unwind across interrupts and exceptions. Frame pointer based 48 + unwinds can sometimes skip the caller of the interrupted function, if it 49 + was a leaf function or if the interrupt hit before the frame pointer was 50 + saved. 51 + 52 + The main disadvantage of the ORC unwinder compared to frame pointers is 53 + that it needs more memory to store the ORC unwind tables: roughly 2-4MB 54 + depending on the kernel config. 55 + 56 + 57 + ORC vs DWARF 58 + ------------ 59 + 60 + ORC debuginfo's advantage over DWARF itself is that it's much simpler. 61 + It gets rid of the complex DWARF CFI state machine and also gets rid of 62 + the tracking of unnecessary registers. This allows the unwinder to be 63 + much simpler, meaning fewer bugs, which is especially important for 64 + mission critical oops code. 65 + 66 + The simpler debuginfo format also enables the unwinder to be much faster 67 + than DWARF, which is important for perf and lockdep. In a basic 68 + performance test by Jiri Slaby [2], the ORC unwinder was about 20x 69 + faster than an out-of-tree DWARF unwinder. (Note: That measurement was 70 + taken before some performance tweaks were added, which doubled 71 + performance, so the speedup over DWARF may be closer to 40x.) 72 + 73 + The ORC data format does have a few downsides compared to DWARF. ORC 74 + unwind tables take up ~50% more RAM (+1.3MB on an x86 defconfig kernel) 75 + than DWARF-based eh_frame tables. 76 + 77 + Another potential downside is that, as GCC evolves, it's conceivable 78 + that the ORC data may end up being *too* simple to describe the state of 79 + the stack for certain optimizations. But IMO this is unlikely because 80 + GCC saves the frame pointer for any unusual stack adjustments it does, 81 + so I suspect we'll really only ever need to keep track of the stack 82 + pointer and the frame pointer between call frames. But even if we do 83 + end up having to track all the registers DWARF tracks, at least we will 84 + still be able to control the format, e.g. no complex state machines. 85 + 86 + 87 + ORC unwind table generation 88 + --------------------------- 89 + 90 + The ORC data is generated by objtool. With the existing compile-time 91 + stack metadata validation feature, objtool already follows all code 92 + paths, and so it already has all the information it needs to be able to 93 + generate ORC data from scratch. So it's an easy step to go from stack 94 + validation to ORC data generation. 95 + 96 + It should be possible to instead generate the ORC data with a simple 97 + tool which converts DWARF to ORC data. However, such a solution would 98 + be incomplete due to the kernel's extensive use of asm, inline asm, and 99 + special sections like exception tables. 100 + 101 + That could be rectified by manually annotating those special code paths 102 + using GNU assembler .cfi annotations in .S files, and homegrown 103 + annotations for inline asm in .c files. But asm annotations were tried 104 + in the past and were found to be unmaintainable. They were often 105 + incorrect/incomplete and made the code harder to read and keep updated. 106 + And based on looking at glibc code, annotating inline asm in .c files 107 + might be even worse. 108 + 109 + Objtool still needs a few annotations, but only in code which does 110 + unusual things to the stack like entry code. And even then, far fewer 111 + annotations are needed than what DWARF would need, so they're much more 112 + maintainable than DWARF CFI annotations. 113 + 114 + So the advantages of using objtool to generate ORC data are that it 115 + gives more accurate debuginfo, with very few annotations. It also 116 + insulates the kernel from toolchain bugs which can be very painful to 117 + deal with in the kernel since we often have to workaround issues in 118 + older versions of the toolchain for years. 119 + 120 + The downside is that the unwinder now becomes dependent on objtool's 121 + ability to reverse engineer GCC code flow. If GCC optimizations become 122 + too complicated for objtool to follow, the ORC data generation might 123 + stop working or become incomplete. (It's worth noting that livepatch 124 + already has such a dependency on objtool's ability to follow GCC code 125 + flow.) 126 + 127 + If newer versions of GCC come up with some optimizations which break 128 + objtool, we may need to revisit the current implementation. Some 129 + possible solutions would be asking GCC to make the optimizations more 130 + palatable, or having objtool use DWARF as an additional input, or 131 + creating a GCC plugin to assist objtool with its analysis. But for now, 132 + objtool follows GCC code quite well. 133 + 134 + 135 + Unwinder implementation details 136 + ------------------------------- 137 + 138 + Objtool generates the ORC data by integrating with the compile-time 139 + stack metadata validation feature, which is described in detail in 140 + tools/objtool/Documentation/stack-validation.txt. After analyzing all 141 + the code paths of a .o file, it creates an array of orc_entry structs, 142 + and a parallel array of instruction addresses associated with those 143 + structs, and writes them to the .orc_unwind and .orc_unwind_ip sections 144 + respectively. 145 + 146 + The ORC data is split into the two arrays for performance reasons, to 147 + make the searchable part of the data (.orc_unwind_ip) more compact. The 148 + arrays are sorted in parallel at boot time. 149 + 150 + Performance is further improved by the use of a fast lookup table which 151 + is created at runtime. The fast lookup table associates a given address 152 + with a range of indices for the .orc_unwind table, so that only a small 153 + subset of the table needs to be searched. 154 + 155 + 156 + Etymology 157 + --------- 158 + 159 + Orcs, fearsome creatures of medieval folklore, are the Dwarves' natural 160 + enemies. Similarly, the ORC unwinder was created in opposition to the 161 + complexity and slowness of DWARF. 162 + 163 + "Although Orcs rarely consider multiple solutions to a problem, they do 164 + excel at getting things done because they are creatures of action, not 165 + thought." [3] Similarly, unlike the esoteric DWARF unwinder, the 166 + veracious ORC unwinder wastes no time or siloconic effort decoding 167 + variable-length zero-extended unsigned-integer byte-coded 168 + state-machine-based debug information entries. 169 + 170 + Similar to how Orcs frequently unravel the well-intentioned plans of 171 + their adversaries, the ORC unwinder frequently unravels stacks with 172 + brutal, unyielding efficiency. 173 + 174 + ORC stands for Oops Rewind Capability. 175 + 176 + 177 + [1] https://lkml.kernel.org/r/20170602104048.jkkzssljsompjdwy@suse.de 178 + [2] https://lkml.kernel.org/r/d2ca5435-6386-29b8-db87-7f227c2b713a@suse.cz 179 + [3] http://dustin.wikidot.com/half-orcs-and-orcs
+8
arch/um/include/asm/unwind.h
··· 1 + #ifndef _ASM_UML_UNWIND_H 2 + #define _ASM_UML_UNWIND_H 3 + 4 + static inline void 5 + unwind_module_init(struct module *mod, void *orc_ip, size_t orc_ip_size, 6 + void *orc, size_t orc_size) {} 7 + 8 + #endif /* _ASM_UML_UNWIND_H */
+1
arch/x86/Kconfig
··· 157 157 select HAVE_MEMBLOCK 158 158 select HAVE_MEMBLOCK_NODE_MAP 159 159 select HAVE_MIXED_BREAKPOINTS_REGS 160 + select HAVE_MOD_ARCH_SPECIFIC 160 161 select HAVE_NMI 161 162 select HAVE_OPROFILE 162 163 select HAVE_OPTPROBES
+25
arch/x86/Kconfig.debug
··· 355 355 The current power state can be read from 356 356 /sys/kernel/debug/punit_atom/dev_power_state 357 357 358 + config ORC_UNWINDER 359 + bool "ORC unwinder" 360 + depends on X86_64 361 + select STACK_VALIDATION 362 + ---help--- 363 + This option enables the ORC (Oops Rewind Capability) unwinder for 364 + unwinding kernel stack traces. It uses a custom data format which is 365 + a simplified version of the DWARF Call Frame Information standard. 366 + 367 + This unwinder is more accurate across interrupt entry frames than the 368 + frame pointer unwinder. It can also enable a 5-10% performance 369 + improvement across the entire kernel if CONFIG_FRAME_POINTER is 370 + disabled. 371 + 372 + Enabling this option will increase the kernel's runtime memory usage 373 + by roughly 2-4MB, depending on your kernel config. 374 + 375 + config FRAME_POINTER_UNWINDER 376 + def_bool y 377 + depends on !ORC_UNWINDER && FRAME_POINTER 378 + 379 + config GUESS_UNWINDER 380 + def_bool y 381 + depends on !ORC_UNWINDER && !FRAME_POINTER 382 + 358 383 endmenu
+9
arch/x86/include/asm/module.h
··· 2 2 #define _ASM_X86_MODULE_H 3 3 4 4 #include <asm-generic/module.h> 5 + #include <asm/orc_types.h> 6 + 7 + struct mod_arch_specific { 8 + #ifdef CONFIG_ORC_UNWINDER 9 + unsigned int num_orcs; 10 + int *orc_unwind_ip; 11 + struct orc_entry *orc_unwind; 12 + #endif 13 + }; 5 14 6 15 #ifdef CONFIG_X86_64 7 16 /* X86_64 does not define MODULE_PROC_FAMILY */
+46
arch/x86/include/asm/orc_lookup.h
··· 1 + /* 2 + * Copyright (C) 2017 Josh Poimboeuf <jpoimboe@redhat.com> 3 + * 4 + * This program is free software; you can redistribute it and/or 5 + * modify it under the terms of the GNU General Public License 6 + * as published by the Free Software Foundation; either version 2 7 + * of the License, or (at your option) any later version. 8 + * 9 + * This program is distributed in the hope that it will be useful, 10 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 + * GNU General Public License for more details. 13 + * 14 + * You should have received a copy of the GNU General Public License 15 + * along with this program; if not, see <http://www.gnu.org/licenses/>. 16 + */ 17 + #ifndef _ORC_LOOKUP_H 18 + #define _ORC_LOOKUP_H 19 + 20 + /* 21 + * This is a lookup table for speeding up access to the .orc_unwind table. 22 + * Given an input address offset, the corresponding lookup table entry 23 + * specifies a subset of the .orc_unwind table to search. 24 + * 25 + * Each block represents the end of the previous range and the start of the 26 + * next range. An extra block is added to give the last range an end. 27 + * 28 + * The block size should be a power of 2 to avoid a costly 'div' instruction. 29 + * 30 + * A block size of 256 was chosen because it roughly doubles unwinder 31 + * performance while only adding ~5% to the ORC data footprint. 32 + */ 33 + #define LOOKUP_BLOCK_ORDER 8 34 + #define LOOKUP_BLOCK_SIZE (1 << LOOKUP_BLOCK_ORDER) 35 + 36 + #ifndef LINKER_SCRIPT 37 + 38 + extern unsigned int orc_lookup[]; 39 + extern unsigned int orc_lookup_end[]; 40 + 41 + #define LOOKUP_START_IP (unsigned long)_stext 42 + #define LOOKUP_STOP_IP (unsigned long)_etext 43 + 44 + #endif /* LINKER_SCRIPT */ 45 + 46 + #endif /* _ORC_LOOKUP_H */
+1 -1
arch/x86/include/asm/orc_types.h
··· 88 88 unsigned sp_reg:4; 89 89 unsigned bp_reg:4; 90 90 unsigned type:2; 91 - }; 91 + } __packed; 92 92 93 93 /* 94 94 * This struct is used by asm and inline asm code to manually annotate the
+50 -32
arch/x86/include/asm/unwind.h
··· 12 12 struct task_struct *task; 13 13 int graph_idx; 14 14 bool error; 15 - #ifdef CONFIG_FRAME_POINTER 16 - bool got_irq; 17 - unsigned long *bp, *orig_sp; 15 + #if defined(CONFIG_ORC_UNWINDER) 16 + bool signal, full_regs; 17 + unsigned long sp, bp, ip; 18 18 struct pt_regs *regs; 19 - unsigned long ip; 19 + #elif defined(CONFIG_FRAME_POINTER) 20 + bool got_irq; 21 + unsigned long *bp, *orig_sp, ip; 22 + struct pt_regs *regs; 20 23 #else 21 24 unsigned long *sp; 22 25 #endif ··· 27 24 28 25 void __unwind_start(struct unwind_state *state, struct task_struct *task, 29 26 struct pt_regs *regs, unsigned long *first_frame); 30 - 31 27 bool unwind_next_frame(struct unwind_state *state); 32 - 33 28 unsigned long unwind_get_return_address(struct unwind_state *state); 29 + unsigned long *unwind_get_return_address_ptr(struct unwind_state *state); 34 30 35 31 static inline bool unwind_done(struct unwind_state *state) 36 32 { 37 33 return state->stack_info.type == STACK_TYPE_UNKNOWN; 34 + } 35 + 36 + static inline bool unwind_error(struct unwind_state *state) 37 + { 38 + return state->error; 38 39 } 39 40 40 41 static inline ··· 50 43 __unwind_start(state, task, regs, first_frame); 51 44 } 52 45 53 - static inline bool unwind_error(struct unwind_state *state) 54 - { 55 - return state->error; 56 - } 57 - 58 - #ifdef CONFIG_FRAME_POINTER 59 - 60 - static inline 61 - unsigned long *unwind_get_return_address_ptr(struct unwind_state *state) 62 - { 63 - if (unwind_done(state)) 64 - return NULL; 65 - 66 - return state->regs ? &state->regs->ip : state->bp + 1; 67 - } 68 - 46 + #if defined(CONFIG_ORC_UNWINDER) || defined(CONFIG_FRAME_POINTER) 69 47 static inline struct pt_regs *unwind_get_entry_regs(struct unwind_state *state) 70 48 { 71 49 if (unwind_done(state)) ··· 58 66 59 67 return state->regs; 60 68 } 61 - 62 - #else /* !CONFIG_FRAME_POINTER */ 63 - 64 - static inline 65 - unsigned long *unwind_get_return_address_ptr(struct unwind_state *state) 66 - { 67 - return NULL; 68 - } 69 - 69 + #else 70 70 static inline struct pt_regs *unwind_get_entry_regs(struct unwind_state *state) 71 71 { 72 72 return NULL; 73 73 } 74 + #endif 74 75 75 - #endif /* CONFIG_FRAME_POINTER */ 76 + #ifdef CONFIG_ORC_UNWINDER 77 + void unwind_init(void); 78 + void unwind_module_init(struct module *mod, void *orc_ip, size_t orc_ip_size, 79 + void *orc, size_t orc_size); 80 + #else 81 + static inline void unwind_init(void) {} 82 + static inline 83 + void unwind_module_init(struct module *mod, void *orc_ip, size_t orc_ip_size, 84 + void *orc, size_t orc_size) {} 85 + #endif 86 + 87 + /* 88 + * This disables KASAN checking when reading a value from another task's stack, 89 + * since the other task could be running on another CPU and could have poisoned 90 + * the stack in the meantime. 91 + */ 92 + #define READ_ONCE_TASK_STACK(task, x) \ 93 + ({ \ 94 + unsigned long val; \ 95 + if (task == current) \ 96 + val = READ_ONCE(x); \ 97 + else \ 98 + val = READ_ONCE_NOCHECK(x); \ 99 + val; \ 100 + }) 101 + 102 + static inline bool task_on_another_cpu(struct task_struct *task) 103 + { 104 + #ifdef CONFIG_SMP 105 + return task != current && task->on_cpu; 106 + #else 107 + return false; 108 + #endif 109 + } 76 110 77 111 #endif /* _ASM_X86_UNWIND_H */
+3 -5
arch/x86/kernel/Makefile
··· 126 126 obj-$(CONFIG_TRACING) += tracepoint.o 127 127 obj-$(CONFIG_SCHED_MC_PRIO) += itmt.o 128 128 129 - ifdef CONFIG_FRAME_POINTER 130 - obj-y += unwind_frame.o 131 - else 132 - obj-y += unwind_guess.o 133 - endif 129 + obj-$(CONFIG_ORC_UNWINDER) += unwind_orc.o 130 + obj-$(CONFIG_FRAME_POINTER_UNWINDER) += unwind_frame.o 131 + obj-$(CONFIG_GUESS_UNWINDER) += unwind_guess.o 134 132 135 133 ### 136 134 # 64 bit specific files
+10 -1
arch/x86/kernel/module.c
··· 35 35 #include <asm/page.h> 36 36 #include <asm/pgtable.h> 37 37 #include <asm/setup.h> 38 + #include <asm/unwind.h> 38 39 39 40 #if 0 40 41 #define DEBUGP(fmt, ...) \ ··· 214 213 struct module *me) 215 214 { 216 215 const Elf_Shdr *s, *text = NULL, *alt = NULL, *locks = NULL, 217 - *para = NULL; 216 + *para = NULL, *orc = NULL, *orc_ip = NULL; 218 217 char *secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; 219 218 220 219 for (s = sechdrs; s < sechdrs + hdr->e_shnum; s++) { ··· 226 225 locks = s; 227 226 if (!strcmp(".parainstructions", secstrings + s->sh_name)) 228 227 para = s; 228 + if (!strcmp(".orc_unwind", secstrings + s->sh_name)) 229 + orc = s; 230 + if (!strcmp(".orc_unwind_ip", secstrings + s->sh_name)) 231 + orc_ip = s; 229 232 } 230 233 231 234 if (alt) { ··· 252 247 253 248 /* make jump label nops */ 254 249 jump_label_apply_nops(me); 250 + 251 + if (orc && orc_ip) 252 + unwind_module_init(me, (void *)orc_ip->sh_addr, orc_ip->sh_size, 253 + (void *)orc->sh_addr, orc->sh_size); 255 254 256 255 return 0; 257 256 }
+3
arch/x86/kernel/setup.c
··· 115 115 #include <asm/microcode.h> 116 116 #include <asm/mmu_context.h> 117 117 #include <asm/kaslr.h> 118 + #include <asm/unwind.h> 118 119 119 120 /* 120 121 * max_low_pfn_mapped: highest direct mapped pfn under 4GB ··· 1311 1310 if (efi_enabled(EFI_BOOT)) 1312 1311 efi_apply_memmap_quirks(); 1313 1312 #endif 1313 + 1314 + unwind_init(); 1314 1315 } 1315 1316 1316 1317 #ifdef CONFIG_X86_32
+16 -23
arch/x86/kernel/unwind_frame.c
··· 10 10 11 11 #define FRAME_HEADER_SIZE (sizeof(long) * 2) 12 12 13 - /* 14 - * This disables KASAN checking when reading a value from another task's stack, 15 - * since the other task could be running on another CPU and could have poisoned 16 - * the stack in the meantime. 17 - */ 18 - #define READ_ONCE_TASK_STACK(task, x) \ 19 - ({ \ 20 - unsigned long val; \ 21 - if (task == current) \ 22 - val = READ_ONCE(x); \ 23 - else \ 24 - val = READ_ONCE_NOCHECK(x); \ 25 - val; \ 26 - }) 13 + unsigned long unwind_get_return_address(struct unwind_state *state) 14 + { 15 + if (unwind_done(state)) 16 + return 0; 17 + 18 + return __kernel_text_address(state->ip) ? state->ip : 0; 19 + } 20 + EXPORT_SYMBOL_GPL(unwind_get_return_address); 21 + 22 + unsigned long *unwind_get_return_address_ptr(struct unwind_state *state) 23 + { 24 + if (unwind_done(state)) 25 + return NULL; 26 + 27 + return state->regs ? &state->regs->ip : state->bp + 1; 28 + } 27 29 28 30 static void unwind_dump(struct unwind_state *state) 29 31 { ··· 67 65 } 68 66 } 69 67 } 70 - 71 - unsigned long unwind_get_return_address(struct unwind_state *state) 72 - { 73 - if (unwind_done(state)) 74 - return 0; 75 - 76 - return __kernel_text_address(state->ip) ? state->ip : 0; 77 - } 78 - EXPORT_SYMBOL_GPL(unwind_get_return_address); 79 68 80 69 static size_t regs_size(struct pt_regs *regs) 81 70 {
+5
arch/x86/kernel/unwind_guess.c
··· 19 19 } 20 20 EXPORT_SYMBOL_GPL(unwind_get_return_address); 21 21 22 + unsigned long *unwind_get_return_address_ptr(struct unwind_state *state) 23 + { 24 + return NULL; 25 + } 26 + 22 27 bool unwind_next_frame(struct unwind_state *state) 23 28 { 24 29 struct stack_info *info = &state->stack_info;
+582
arch/x86/kernel/unwind_orc.c
··· 1 + #include <linux/module.h> 2 + #include <linux/sort.h> 3 + #include <asm/ptrace.h> 4 + #include <asm/stacktrace.h> 5 + #include <asm/unwind.h> 6 + #include <asm/orc_types.h> 7 + #include <asm/orc_lookup.h> 8 + #include <asm/sections.h> 9 + 10 + #define orc_warn(fmt, ...) \ 11 + printk_deferred_once(KERN_WARNING pr_fmt("WARNING: " fmt), ##__VA_ARGS__) 12 + 13 + extern int __start_orc_unwind_ip[]; 14 + extern int __stop_orc_unwind_ip[]; 15 + extern struct orc_entry __start_orc_unwind[]; 16 + extern struct orc_entry __stop_orc_unwind[]; 17 + 18 + static DEFINE_MUTEX(sort_mutex); 19 + int *cur_orc_ip_table = __start_orc_unwind_ip; 20 + struct orc_entry *cur_orc_table = __start_orc_unwind; 21 + 22 + unsigned int lookup_num_blocks; 23 + bool orc_init; 24 + 25 + static inline unsigned long orc_ip(const int *ip) 26 + { 27 + return (unsigned long)ip + *ip; 28 + } 29 + 30 + static struct orc_entry *__orc_find(int *ip_table, struct orc_entry *u_table, 31 + unsigned int num_entries, unsigned long ip) 32 + { 33 + int *first = ip_table; 34 + int *last = ip_table + num_entries - 1; 35 + int *mid = first, *found = first; 36 + 37 + if (!num_entries) 38 + return NULL; 39 + 40 + /* 41 + * Do a binary range search to find the rightmost duplicate of a given 42 + * starting address. Some entries are section terminators which are 43 + * "weak" entries for ensuring there are no gaps. They should be 44 + * ignored when they conflict with a real entry. 45 + */ 46 + while (first <= last) { 47 + mid = first + ((last - first) / 2); 48 + 49 + if (orc_ip(mid) <= ip) { 50 + found = mid; 51 + first = mid + 1; 52 + } else 53 + last = mid - 1; 54 + } 55 + 56 + return u_table + (found - ip_table); 57 + } 58 + 59 + #ifdef CONFIG_MODULES 60 + static struct orc_entry *orc_module_find(unsigned long ip) 61 + { 62 + struct module *mod; 63 + 64 + mod = __module_address(ip); 65 + if (!mod || !mod->arch.orc_unwind || !mod->arch.orc_unwind_ip) 66 + return NULL; 67 + return __orc_find(mod->arch.orc_unwind_ip, mod->arch.orc_unwind, 68 + mod->arch.num_orcs, ip); 69 + } 70 + #else 71 + static struct orc_entry *orc_module_find(unsigned long ip) 72 + { 73 + return NULL; 74 + } 75 + #endif 76 + 77 + static struct orc_entry *orc_find(unsigned long ip) 78 + { 79 + if (!orc_init) 80 + return NULL; 81 + 82 + /* For non-init vmlinux addresses, use the fast lookup table: */ 83 + if (ip >= LOOKUP_START_IP && ip < LOOKUP_STOP_IP) { 84 + unsigned int idx, start, stop; 85 + 86 + idx = (ip - LOOKUP_START_IP) / LOOKUP_BLOCK_SIZE; 87 + 88 + if (unlikely((idx >= lookup_num_blocks-1))) { 89 + orc_warn("WARNING: bad lookup idx: idx=%u num=%u ip=%lx\n", 90 + idx, lookup_num_blocks, ip); 91 + return NULL; 92 + } 93 + 94 + start = orc_lookup[idx]; 95 + stop = orc_lookup[idx + 1] + 1; 96 + 97 + if (unlikely((__start_orc_unwind + start >= __stop_orc_unwind) || 98 + (__start_orc_unwind + stop > __stop_orc_unwind))) { 99 + orc_warn("WARNING: bad lookup value: idx=%u num=%u start=%u stop=%u ip=%lx\n", 100 + idx, lookup_num_blocks, start, stop, ip); 101 + return NULL; 102 + } 103 + 104 + return __orc_find(__start_orc_unwind_ip + start, 105 + __start_orc_unwind + start, stop - start, ip); 106 + } 107 + 108 + /* vmlinux .init slow lookup: */ 109 + if (ip >= (unsigned long)_sinittext && ip < (unsigned long)_einittext) 110 + return __orc_find(__start_orc_unwind_ip, __start_orc_unwind, 111 + __stop_orc_unwind_ip - __start_orc_unwind_ip, ip); 112 + 113 + /* Module lookup: */ 114 + return orc_module_find(ip); 115 + } 116 + 117 + static void orc_sort_swap(void *_a, void *_b, int size) 118 + { 119 + struct orc_entry *orc_a, *orc_b; 120 + struct orc_entry orc_tmp; 121 + int *a = _a, *b = _b, tmp; 122 + int delta = _b - _a; 123 + 124 + /* Swap the .orc_unwind_ip entries: */ 125 + tmp = *a; 126 + *a = *b + delta; 127 + *b = tmp - delta; 128 + 129 + /* Swap the corresponding .orc_unwind entries: */ 130 + orc_a = cur_orc_table + (a - cur_orc_ip_table); 131 + orc_b = cur_orc_table + (b - cur_orc_ip_table); 132 + orc_tmp = *orc_a; 133 + *orc_a = *orc_b; 134 + *orc_b = orc_tmp; 135 + } 136 + 137 + static int orc_sort_cmp(const void *_a, const void *_b) 138 + { 139 + struct orc_entry *orc_a; 140 + const int *a = _a, *b = _b; 141 + unsigned long a_val = orc_ip(a); 142 + unsigned long b_val = orc_ip(b); 143 + 144 + if (a_val > b_val) 145 + return 1; 146 + if (a_val < b_val) 147 + return -1; 148 + 149 + /* 150 + * The "weak" section terminator entries need to always be on the left 151 + * to ensure the lookup code skips them in favor of real entries. 152 + * These terminator entries exist to handle any gaps created by 153 + * whitelisted .o files which didn't get objtool generation. 154 + */ 155 + orc_a = cur_orc_table + (a - cur_orc_ip_table); 156 + return orc_a->sp_reg == ORC_REG_UNDEFINED ? -1 : 1; 157 + } 158 + 159 + #ifdef CONFIG_MODULES 160 + void unwind_module_init(struct module *mod, void *_orc_ip, size_t orc_ip_size, 161 + void *_orc, size_t orc_size) 162 + { 163 + int *orc_ip = _orc_ip; 164 + struct orc_entry *orc = _orc; 165 + unsigned int num_entries = orc_ip_size / sizeof(int); 166 + 167 + WARN_ON_ONCE(orc_ip_size % sizeof(int) != 0 || 168 + orc_size % sizeof(*orc) != 0 || 169 + num_entries != orc_size / sizeof(*orc)); 170 + 171 + /* 172 + * The 'cur_orc_*' globals allow the orc_sort_swap() callback to 173 + * associate an .orc_unwind_ip table entry with its corresponding 174 + * .orc_unwind entry so they can both be swapped. 175 + */ 176 + mutex_lock(&sort_mutex); 177 + cur_orc_ip_table = orc_ip; 178 + cur_orc_table = orc; 179 + sort(orc_ip, num_entries, sizeof(int), orc_sort_cmp, orc_sort_swap); 180 + mutex_unlock(&sort_mutex); 181 + 182 + mod->arch.orc_unwind_ip = orc_ip; 183 + mod->arch.orc_unwind = orc; 184 + mod->arch.num_orcs = num_entries; 185 + } 186 + #endif 187 + 188 + void __init unwind_init(void) 189 + { 190 + size_t orc_ip_size = (void *)__stop_orc_unwind_ip - (void *)__start_orc_unwind_ip; 191 + size_t orc_size = (void *)__stop_orc_unwind - (void *)__start_orc_unwind; 192 + size_t num_entries = orc_ip_size / sizeof(int); 193 + struct orc_entry *orc; 194 + int i; 195 + 196 + if (!num_entries || orc_ip_size % sizeof(int) != 0 || 197 + orc_size % sizeof(struct orc_entry) != 0 || 198 + num_entries != orc_size / sizeof(struct orc_entry)) { 199 + orc_warn("WARNING: Bad or missing .orc_unwind table. Disabling unwinder.\n"); 200 + return; 201 + } 202 + 203 + /* Sort the .orc_unwind and .orc_unwind_ip tables: */ 204 + sort(__start_orc_unwind_ip, num_entries, sizeof(int), orc_sort_cmp, 205 + orc_sort_swap); 206 + 207 + /* Initialize the fast lookup table: */ 208 + lookup_num_blocks = orc_lookup_end - orc_lookup; 209 + for (i = 0; i < lookup_num_blocks-1; i++) { 210 + orc = __orc_find(__start_orc_unwind_ip, __start_orc_unwind, 211 + num_entries, 212 + LOOKUP_START_IP + (LOOKUP_BLOCK_SIZE * i)); 213 + if (!orc) { 214 + orc_warn("WARNING: Corrupt .orc_unwind table. Disabling unwinder.\n"); 215 + return; 216 + } 217 + 218 + orc_lookup[i] = orc - __start_orc_unwind; 219 + } 220 + 221 + /* Initialize the ending block: */ 222 + orc = __orc_find(__start_orc_unwind_ip, __start_orc_unwind, num_entries, 223 + LOOKUP_STOP_IP); 224 + if (!orc) { 225 + orc_warn("WARNING: Corrupt .orc_unwind table. Disabling unwinder.\n"); 226 + return; 227 + } 228 + orc_lookup[lookup_num_blocks-1] = orc - __start_orc_unwind; 229 + 230 + orc_init = true; 231 + } 232 + 233 + unsigned long unwind_get_return_address(struct unwind_state *state) 234 + { 235 + if (unwind_done(state)) 236 + return 0; 237 + 238 + return __kernel_text_address(state->ip) ? state->ip : 0; 239 + } 240 + EXPORT_SYMBOL_GPL(unwind_get_return_address); 241 + 242 + unsigned long *unwind_get_return_address_ptr(struct unwind_state *state) 243 + { 244 + if (unwind_done(state)) 245 + return NULL; 246 + 247 + if (state->regs) 248 + return &state->regs->ip; 249 + 250 + if (state->sp) 251 + return (unsigned long *)state->sp - 1; 252 + 253 + return NULL; 254 + } 255 + 256 + static bool stack_access_ok(struct unwind_state *state, unsigned long addr, 257 + size_t len) 258 + { 259 + struct stack_info *info = &state->stack_info; 260 + 261 + /* 262 + * If the address isn't on the current stack, switch to the next one. 263 + * 264 + * We may have to traverse multiple stacks to deal with the possibility 265 + * that info->next_sp could point to an empty stack and the address 266 + * could be on a subsequent stack. 267 + */ 268 + while (!on_stack(info, (void *)addr, len)) 269 + if (get_stack_info(info->next_sp, state->task, info, 270 + &state->stack_mask)) 271 + return false; 272 + 273 + return true; 274 + } 275 + 276 + static bool deref_stack_reg(struct unwind_state *state, unsigned long addr, 277 + unsigned long *val) 278 + { 279 + if (!stack_access_ok(state, addr, sizeof(long))) 280 + return false; 281 + 282 + *val = READ_ONCE_TASK_STACK(state->task, *(unsigned long *)addr); 283 + return true; 284 + } 285 + 286 + #define REGS_SIZE (sizeof(struct pt_regs)) 287 + #define SP_OFFSET (offsetof(struct pt_regs, sp)) 288 + #define IRET_REGS_SIZE (REGS_SIZE - offsetof(struct pt_regs, ip)) 289 + #define IRET_SP_OFFSET (SP_OFFSET - offsetof(struct pt_regs, ip)) 290 + 291 + static bool deref_stack_regs(struct unwind_state *state, unsigned long addr, 292 + unsigned long *ip, unsigned long *sp, bool full) 293 + { 294 + size_t regs_size = full ? REGS_SIZE : IRET_REGS_SIZE; 295 + size_t sp_offset = full ? SP_OFFSET : IRET_SP_OFFSET; 296 + struct pt_regs *regs = (struct pt_regs *)(addr + regs_size - REGS_SIZE); 297 + 298 + if (IS_ENABLED(CONFIG_X86_64)) { 299 + if (!stack_access_ok(state, addr, regs_size)) 300 + return false; 301 + 302 + *ip = regs->ip; 303 + *sp = regs->sp; 304 + 305 + return true; 306 + } 307 + 308 + if (!stack_access_ok(state, addr, sp_offset)) 309 + return false; 310 + 311 + *ip = regs->ip; 312 + 313 + if (user_mode(regs)) { 314 + if (!stack_access_ok(state, addr + sp_offset, 315 + REGS_SIZE - SP_OFFSET)) 316 + return false; 317 + 318 + *sp = regs->sp; 319 + } else 320 + *sp = (unsigned long)&regs->sp; 321 + 322 + return true; 323 + } 324 + 325 + bool unwind_next_frame(struct unwind_state *state) 326 + { 327 + unsigned long ip_p, sp, orig_ip, prev_sp = state->sp; 328 + enum stack_type prev_type = state->stack_info.type; 329 + struct orc_entry *orc; 330 + struct pt_regs *ptregs; 331 + bool indirect = false; 332 + 333 + if (unwind_done(state)) 334 + return false; 335 + 336 + /* Don't let modules unload while we're reading their ORC data. */ 337 + preempt_disable(); 338 + 339 + /* Have we reached the end? */ 340 + if (state->regs && user_mode(state->regs)) 341 + goto done; 342 + 343 + /* 344 + * Find the orc_entry associated with the text address. 345 + * 346 + * Decrement call return addresses by one so they work for sibling 347 + * calls and calls to noreturn functions. 348 + */ 349 + orc = orc_find(state->signal ? state->ip : state->ip - 1); 350 + if (!orc || orc->sp_reg == ORC_REG_UNDEFINED) 351 + goto done; 352 + orig_ip = state->ip; 353 + 354 + /* Find the previous frame's stack: */ 355 + switch (orc->sp_reg) { 356 + case ORC_REG_SP: 357 + sp = state->sp + orc->sp_offset; 358 + break; 359 + 360 + case ORC_REG_BP: 361 + sp = state->bp + orc->sp_offset; 362 + break; 363 + 364 + case ORC_REG_SP_INDIRECT: 365 + sp = state->sp + orc->sp_offset; 366 + indirect = true; 367 + break; 368 + 369 + case ORC_REG_BP_INDIRECT: 370 + sp = state->bp + orc->sp_offset; 371 + indirect = true; 372 + break; 373 + 374 + case ORC_REG_R10: 375 + if (!state->regs || !state->full_regs) { 376 + orc_warn("missing regs for base reg R10 at ip %p\n", 377 + (void *)state->ip); 378 + goto done; 379 + } 380 + sp = state->regs->r10; 381 + break; 382 + 383 + case ORC_REG_R13: 384 + if (!state->regs || !state->full_regs) { 385 + orc_warn("missing regs for base reg R13 at ip %p\n", 386 + (void *)state->ip); 387 + goto done; 388 + } 389 + sp = state->regs->r13; 390 + break; 391 + 392 + case ORC_REG_DI: 393 + if (!state->regs || !state->full_regs) { 394 + orc_warn("missing regs for base reg DI at ip %p\n", 395 + (void *)state->ip); 396 + goto done; 397 + } 398 + sp = state->regs->di; 399 + break; 400 + 401 + case ORC_REG_DX: 402 + if (!state->regs || !state->full_regs) { 403 + orc_warn("missing regs for base reg DX at ip %p\n", 404 + (void *)state->ip); 405 + goto done; 406 + } 407 + sp = state->regs->dx; 408 + break; 409 + 410 + default: 411 + orc_warn("unknown SP base reg %d for ip %p\n", 412 + orc->sp_reg, (void *)state->ip); 413 + goto done; 414 + } 415 + 416 + if (indirect) { 417 + if (!deref_stack_reg(state, sp, &sp)) 418 + goto done; 419 + } 420 + 421 + /* Find IP, SP and possibly regs: */ 422 + switch (orc->type) { 423 + case ORC_TYPE_CALL: 424 + ip_p = sp - sizeof(long); 425 + 426 + if (!deref_stack_reg(state, ip_p, &state->ip)) 427 + goto done; 428 + 429 + state->ip = ftrace_graph_ret_addr(state->task, &state->graph_idx, 430 + state->ip, (void *)ip_p); 431 + 432 + state->sp = sp; 433 + state->regs = NULL; 434 + state->signal = false; 435 + break; 436 + 437 + case ORC_TYPE_REGS: 438 + if (!deref_stack_regs(state, sp, &state->ip, &state->sp, true)) { 439 + orc_warn("can't dereference registers at %p for ip %p\n", 440 + (void *)sp, (void *)orig_ip); 441 + goto done; 442 + } 443 + 444 + state->regs = (struct pt_regs *)sp; 445 + state->full_regs = true; 446 + state->signal = true; 447 + break; 448 + 449 + case ORC_TYPE_REGS_IRET: 450 + if (!deref_stack_regs(state, sp, &state->ip, &state->sp, false)) { 451 + orc_warn("can't dereference iret registers at %p for ip %p\n", 452 + (void *)sp, (void *)orig_ip); 453 + goto done; 454 + } 455 + 456 + ptregs = container_of((void *)sp, struct pt_regs, ip); 457 + if ((unsigned long)ptregs >= prev_sp && 458 + on_stack(&state->stack_info, ptregs, REGS_SIZE)) { 459 + state->regs = ptregs; 460 + state->full_regs = false; 461 + } else 462 + state->regs = NULL; 463 + 464 + state->signal = true; 465 + break; 466 + 467 + default: 468 + orc_warn("unknown .orc_unwind entry type %d\n", orc->type); 469 + break; 470 + } 471 + 472 + /* Find BP: */ 473 + switch (orc->bp_reg) { 474 + case ORC_REG_UNDEFINED: 475 + if (state->regs && state->full_regs) 476 + state->bp = state->regs->bp; 477 + break; 478 + 479 + case ORC_REG_PREV_SP: 480 + if (!deref_stack_reg(state, sp + orc->bp_offset, &state->bp)) 481 + goto done; 482 + break; 483 + 484 + case ORC_REG_BP: 485 + if (!deref_stack_reg(state, state->bp + orc->bp_offset, &state->bp)) 486 + goto done; 487 + break; 488 + 489 + default: 490 + orc_warn("unknown BP base reg %d for ip %p\n", 491 + orc->bp_reg, (void *)orig_ip); 492 + goto done; 493 + } 494 + 495 + /* Prevent a recursive loop due to bad ORC data: */ 496 + if (state->stack_info.type == prev_type && 497 + on_stack(&state->stack_info, (void *)state->sp, sizeof(long)) && 498 + state->sp <= prev_sp) { 499 + orc_warn("stack going in the wrong direction? ip=%p\n", 500 + (void *)orig_ip); 501 + goto done; 502 + } 503 + 504 + preempt_enable(); 505 + return true; 506 + 507 + done: 508 + preempt_enable(); 509 + state->stack_info.type = STACK_TYPE_UNKNOWN; 510 + return false; 511 + } 512 + EXPORT_SYMBOL_GPL(unwind_next_frame); 513 + 514 + void __unwind_start(struct unwind_state *state, struct task_struct *task, 515 + struct pt_regs *regs, unsigned long *first_frame) 516 + { 517 + memset(state, 0, sizeof(*state)); 518 + state->task = task; 519 + 520 + /* 521 + * Refuse to unwind the stack of a task while it's executing on another 522 + * CPU. This check is racy, but that's ok: the unwinder has other 523 + * checks to prevent it from going off the rails. 524 + */ 525 + if (task_on_another_cpu(task)) 526 + goto done; 527 + 528 + if (regs) { 529 + if (user_mode(regs)) 530 + goto done; 531 + 532 + state->ip = regs->ip; 533 + state->sp = kernel_stack_pointer(regs); 534 + state->bp = regs->bp; 535 + state->regs = regs; 536 + state->full_regs = true; 537 + state->signal = true; 538 + 539 + } else if (task == current) { 540 + asm volatile("lea (%%rip), %0\n\t" 541 + "mov %%rsp, %1\n\t" 542 + "mov %%rbp, %2\n\t" 543 + : "=r" (state->ip), "=r" (state->sp), 544 + "=r" (state->bp)); 545 + 546 + } else { 547 + struct inactive_task_frame *frame = (void *)task->thread.sp; 548 + 549 + state->sp = task->thread.sp; 550 + state->bp = READ_ONCE_NOCHECK(frame->bp); 551 + state->ip = READ_ONCE_NOCHECK(frame->ret_addr); 552 + } 553 + 554 + if (get_stack_info((unsigned long *)state->sp, state->task, 555 + &state->stack_info, &state->stack_mask)) 556 + return; 557 + 558 + /* 559 + * The caller can provide the address of the first frame directly 560 + * (first_frame) or indirectly (regs->sp) to indicate which stack frame 561 + * to start unwinding at. Skip ahead until we reach it. 562 + */ 563 + 564 + /* When starting from regs, skip the regs frame: */ 565 + if (regs) { 566 + unwind_next_frame(state); 567 + return; 568 + } 569 + 570 + /* Otherwise, skip ahead to the user-specified starting frame: */ 571 + while (!unwind_done(state) && 572 + (!on_stack(&state->stack_info, first_frame, sizeof(long)) || 573 + state->sp <= (unsigned long)first_frame)) 574 + unwind_next_frame(state); 575 + 576 + return; 577 + 578 + done: 579 + state->stack_info.type = STACK_TYPE_UNKNOWN; 580 + return; 581 + } 582 + EXPORT_SYMBOL_GPL(__unwind_start);
+3
arch/x86/kernel/vmlinux.lds.S
··· 24 24 #include <asm/asm-offsets.h> 25 25 #include <asm/thread_info.h> 26 26 #include <asm/page_types.h> 27 + #include <asm/orc_lookup.h> 27 28 #include <asm/cache.h> 28 29 #include <asm/boot.h> 29 30 ··· 148 147 } :data 149 148 150 149 BUG_TABLE 150 + 151 + ORC_UNWIND_TABLE 151 152 152 153 . = ALIGN(PAGE_SIZE); 153 154 __vvar_page = .;
+26 -1
include/asm-generic/vmlinux.lds.h
··· 680 680 #define BUG_TABLE 681 681 #endif 682 682 683 + #ifdef CONFIG_ORC_UNWINDER 684 + #define ORC_UNWIND_TABLE \ 685 + . = ALIGN(4); \ 686 + .orc_unwind_ip : AT(ADDR(.orc_unwind_ip) - LOAD_OFFSET) { \ 687 + VMLINUX_SYMBOL(__start_orc_unwind_ip) = .; \ 688 + KEEP(*(.orc_unwind_ip)) \ 689 + VMLINUX_SYMBOL(__stop_orc_unwind_ip) = .; \ 690 + } \ 691 + . = ALIGN(6); \ 692 + .orc_unwind : AT(ADDR(.orc_unwind) - LOAD_OFFSET) { \ 693 + VMLINUX_SYMBOL(__start_orc_unwind) = .; \ 694 + KEEP(*(.orc_unwind)) \ 695 + VMLINUX_SYMBOL(__stop_orc_unwind) = .; \ 696 + } \ 697 + . = ALIGN(4); \ 698 + .orc_lookup : AT(ADDR(.orc_lookup) - LOAD_OFFSET) { \ 699 + VMLINUX_SYMBOL(orc_lookup) = .; \ 700 + . += (((SIZEOF(.text) + LOOKUP_BLOCK_SIZE - 1) / \ 701 + LOOKUP_BLOCK_SIZE) + 1) * 4; \ 702 + VMLINUX_SYMBOL(orc_lookup_end) = .; \ 703 + } 704 + #else 705 + #define ORC_UNWIND_TABLE 706 + #endif 707 + 683 708 #ifdef CONFIG_PM_TRACE 684 709 #define TRACEDATA \ 685 710 . = ALIGN(4); \ ··· 891 866 DATA_DATA \ 892 867 CONSTRUCTORS \ 893 868 } \ 894 - BUG_TABLE 869 + BUG_TABLE \ 895 870 896 871 #define INIT_TEXT_SECTION(inittext_align) \ 897 872 . = ALIGN(inittext_align); \
+3
lib/Kconfig.debug
··· 374 374 pointers (if CONFIG_FRAME_POINTER is enabled). This helps ensure 375 375 that runtime stack traces are more reliable. 376 376 377 + This is also a prerequisite for generation of ORC unwind data, which 378 + is needed for CONFIG_ORC_UNWINDER. 379 + 377 380 For more information, see 378 381 tools/objtool/Documentation/stack-validation.txt. 379 382
+10 -4
scripts/Makefile.build
··· 258 258 259 259 __objtool_obj := $(objtree)/tools/objtool/objtool 260 260 261 - objtool_args = check 261 + objtool_args = $(if $(CONFIG_ORC_UNWINDER),orc generate,check) 262 + 262 263 ifndef CONFIG_FRAME_POINTER 263 264 objtool_args += --no-fp 264 265 endif ··· 279 278 280 279 endif # SKIP_STACK_VALIDATION 281 280 endif # CONFIG_STACK_VALIDATION 281 + 282 + # Rebuild all objects when objtool changes, or is enabled/disabled. 283 + objtool_dep = $(objtool_obj) \ 284 + $(wildcard include/config/orc/unwinder.h \ 285 + include/config/stack/validation.h) 282 286 283 287 define rule_cc_o_c 284 288 $(call echo-cmd,checksrc) $(cmd_checksrc) \ ··· 307 301 endif 308 302 309 303 # Built-in and composite module parts 310 - $(obj)/%.o: $(src)/%.c $(recordmcount_source) $(objtool_obj) FORCE 304 + $(obj)/%.o: $(src)/%.c $(recordmcount_source) $(objtool_dep) FORCE 311 305 $(call cmd,force_checksrc) 312 306 $(call if_changed_rule,cc_o_c) 313 307 314 308 # Single-part modules are special since we need to mark them in $(MODVERDIR) 315 309 316 - $(single-used-m): $(obj)/%.o: $(src)/%.c $(recordmcount_source) $(objtool_obj) FORCE 310 + $(single-used-m): $(obj)/%.o: $(src)/%.c $(recordmcount_source) $(objtool_dep) FORCE 317 311 $(call cmd,force_checksrc) 318 312 $(call if_changed_rule,cc_o_c) 319 313 @{ echo $(@:.o=.ko); echo $@; \ ··· 408 402 endif 409 403 endif 410 404 411 - $(obj)/%.o: $(src)/%.S $(objtool_obj) FORCE 405 + $(obj)/%.o: $(src)/%.S $(objtool_dep) FORCE 412 406 $(call if_changed_rule,as_o_S) 413 407 414 408 targets += $(real-objs-y) $(real-objs-m) $(lib-y)