1*4882a593SmuzhiyunCompile-time stack metadata validation 2*4882a593Smuzhiyun====================================== 3*4882a593Smuzhiyun 4*4882a593Smuzhiyun 5*4882a593SmuzhiyunOverview 6*4882a593Smuzhiyun-------- 7*4882a593Smuzhiyun 8*4882a593SmuzhiyunThe kernel CONFIG_STACK_VALIDATION option enables a host tool named 9*4882a593Smuzhiyunobjtool which runs at compile time. It has a "check" subcommand which 10*4882a593Smuzhiyunanalyzes every .o file and ensures the validity of its stack metadata. 11*4882a593SmuzhiyunIt enforces a set of rules on asm code and C inline assembly code so 12*4882a593Smuzhiyunthat stack traces can be reliable. 13*4882a593Smuzhiyun 14*4882a593SmuzhiyunFor each function, it recursively follows all possible code paths and 15*4882a593Smuzhiyunvalidates the correct frame pointer state at each instruction. 16*4882a593Smuzhiyun 17*4882a593SmuzhiyunIt also follows code paths involving special sections, like 18*4882a593Smuzhiyun.altinstructions, __jump_table, and __ex_table, which can add 19*4882a593Smuzhiyunalternative execution paths to a given instruction (or set of 20*4882a593Smuzhiyuninstructions). Similarly, it knows how to follow switch statements, for 21*4882a593Smuzhiyunwhich gcc sometimes uses jump tables. 22*4882a593Smuzhiyun 23*4882a593Smuzhiyun(Objtool also has an 'orc generate' subcommand which generates debuginfo 24*4882a593Smuzhiyunfor the ORC unwinder. See Documentation/x86/orc-unwinder.rst in the 25*4882a593Smuzhiyunkernel tree for more details.) 26*4882a593Smuzhiyun 27*4882a593Smuzhiyun 28*4882a593SmuzhiyunWhy do we need stack metadata validation? 29*4882a593Smuzhiyun----------------------------------------- 30*4882a593Smuzhiyun 31*4882a593SmuzhiyunHere are some of the benefits of validating stack metadata: 32*4882a593Smuzhiyun 33*4882a593Smuzhiyuna) More reliable stack traces for frame pointer enabled kernels 34*4882a593Smuzhiyun 35*4882a593Smuzhiyun Frame pointers are used for debugging purposes. They allow runtime 36*4882a593Smuzhiyun code and debug tools to be able to walk the stack to determine the 37*4882a593Smuzhiyun chain of function call sites that led to the currently executing 38*4882a593Smuzhiyun code. 39*4882a593Smuzhiyun 40*4882a593Smuzhiyun For some architectures, frame pointers are enabled by 41*4882a593Smuzhiyun CONFIG_FRAME_POINTER. For some other architectures they may be 42*4882a593Smuzhiyun required by the ABI (sometimes referred to as "backchain pointers"). 43*4882a593Smuzhiyun 44*4882a593Smuzhiyun For C code, gcc automatically generates instructions for setting up 45*4882a593Smuzhiyun frame pointers when the -fno-omit-frame-pointer option is used. 46*4882a593Smuzhiyun 47*4882a593Smuzhiyun But for asm code, the frame setup instructions have to be written by 48*4882a593Smuzhiyun hand, which most people don't do. So the end result is that 49*4882a593Smuzhiyun CONFIG_FRAME_POINTER is honored for C code but not for most asm code. 50*4882a593Smuzhiyun 51*4882a593Smuzhiyun For stack traces based on frame pointers to be reliable, all 52*4882a593Smuzhiyun functions which call other functions must first create a stack frame 53*4882a593Smuzhiyun and update the frame pointer. If a first function doesn't properly 54*4882a593Smuzhiyun create a stack frame before calling a second function, the *caller* 55*4882a593Smuzhiyun of the first function will be skipped on the stack trace. 56*4882a593Smuzhiyun 57*4882a593Smuzhiyun For example, consider the following example backtrace with frame 58*4882a593Smuzhiyun pointers enabled: 59*4882a593Smuzhiyun 60*4882a593Smuzhiyun [<ffffffff81812584>] dump_stack+0x4b/0x63 61*4882a593Smuzhiyun [<ffffffff812d6dc2>] cmdline_proc_show+0x12/0x30 62*4882a593Smuzhiyun [<ffffffff8127f568>] seq_read+0x108/0x3e0 63*4882a593Smuzhiyun [<ffffffff812cce62>] proc_reg_read+0x42/0x70 64*4882a593Smuzhiyun [<ffffffff81256197>] __vfs_read+0x37/0x100 65*4882a593Smuzhiyun [<ffffffff81256b16>] vfs_read+0x86/0x130 66*4882a593Smuzhiyun [<ffffffff81257898>] SyS_read+0x58/0xd0 67*4882a593Smuzhiyun [<ffffffff8181c1f2>] entry_SYSCALL_64_fastpath+0x12/0x76 68*4882a593Smuzhiyun 69*4882a593Smuzhiyun It correctly shows that the caller of cmdline_proc_show() is 70*4882a593Smuzhiyun seq_read(). 71*4882a593Smuzhiyun 72*4882a593Smuzhiyun If we remove the frame pointer logic from cmdline_proc_show() by 73*4882a593Smuzhiyun replacing the frame pointer related instructions with nops, here's 74*4882a593Smuzhiyun what it looks like instead: 75*4882a593Smuzhiyun 76*4882a593Smuzhiyun [<ffffffff81812584>] dump_stack+0x4b/0x63 77*4882a593Smuzhiyun [<ffffffff812d6dc2>] cmdline_proc_show+0x12/0x30 78*4882a593Smuzhiyun [<ffffffff812cce62>] proc_reg_read+0x42/0x70 79*4882a593Smuzhiyun [<ffffffff81256197>] __vfs_read+0x37/0x100 80*4882a593Smuzhiyun [<ffffffff81256b16>] vfs_read+0x86/0x130 81*4882a593Smuzhiyun [<ffffffff81257898>] SyS_read+0x58/0xd0 82*4882a593Smuzhiyun [<ffffffff8181c1f2>] entry_SYSCALL_64_fastpath+0x12/0x76 83*4882a593Smuzhiyun 84*4882a593Smuzhiyun Notice that cmdline_proc_show()'s caller, seq_read(), has been 85*4882a593Smuzhiyun skipped. Instead the stack trace seems to show that 86*4882a593Smuzhiyun cmdline_proc_show() was called by proc_reg_read(). 87*4882a593Smuzhiyun 88*4882a593Smuzhiyun The benefit of objtool here is that because it ensures that *all* 89*4882a593Smuzhiyun functions honor CONFIG_FRAME_POINTER, no functions will ever[*] be 90*4882a593Smuzhiyun skipped on a stack trace. 91*4882a593Smuzhiyun 92*4882a593Smuzhiyun [*] unless an interrupt or exception has occurred at the very 93*4882a593Smuzhiyun beginning of a function before the stack frame has been created, 94*4882a593Smuzhiyun or at the very end of the function after the stack frame has been 95*4882a593Smuzhiyun destroyed. This is an inherent limitation of frame pointers. 96*4882a593Smuzhiyun 97*4882a593Smuzhiyunb) ORC (Oops Rewind Capability) unwind table generation 98*4882a593Smuzhiyun 99*4882a593Smuzhiyun An alternative to frame pointers and DWARF, ORC unwind data can be 100*4882a593Smuzhiyun used to walk the stack. Unlike frame pointers, ORC data is out of 101*4882a593Smuzhiyun band. So it doesn't affect runtime performance and it can be 102*4882a593Smuzhiyun reliable even when interrupts or exceptions are involved. 103*4882a593Smuzhiyun 104*4882a593Smuzhiyun For more details, see Documentation/x86/orc-unwinder.rst. 105*4882a593Smuzhiyun 106*4882a593Smuzhiyunc) Higher live patching compatibility rate 107*4882a593Smuzhiyun 108*4882a593Smuzhiyun Livepatch has an optional "consistency model", which is needed for 109*4882a593Smuzhiyun more complex patches. In order for the consistency model to work, 110*4882a593Smuzhiyun stack traces need to be reliable (or an unreliable condition needs to 111*4882a593Smuzhiyun be detectable). Objtool makes that possible. 112*4882a593Smuzhiyun 113*4882a593Smuzhiyun For more details, see the livepatch documentation in the Linux kernel 114*4882a593Smuzhiyun source tree at Documentation/livepatch/livepatch.rst. 115*4882a593Smuzhiyun 116*4882a593SmuzhiyunRules 117*4882a593Smuzhiyun----- 118*4882a593Smuzhiyun 119*4882a593SmuzhiyunTo achieve the validation, objtool enforces the following rules: 120*4882a593Smuzhiyun 121*4882a593Smuzhiyun1. Each callable function must be annotated as such with the ELF 122*4882a593Smuzhiyun function type. In asm code, this is typically done using the 123*4882a593Smuzhiyun ENTRY/ENDPROC macros. If objtool finds a return instruction 124*4882a593Smuzhiyun outside of a function, it flags an error since that usually indicates 125*4882a593Smuzhiyun callable code which should be annotated accordingly. 126*4882a593Smuzhiyun 127*4882a593Smuzhiyun This rule is needed so that objtool can properly identify each 128*4882a593Smuzhiyun callable function in order to analyze its stack metadata. 129*4882a593Smuzhiyun 130*4882a593Smuzhiyun2. Conversely, each section of code which is *not* callable should *not* 131*4882a593Smuzhiyun be annotated as an ELF function. The ENDPROC macro shouldn't be used 132*4882a593Smuzhiyun in this case. 133*4882a593Smuzhiyun 134*4882a593Smuzhiyun This rule is needed so that objtool can ignore non-callable code. 135*4882a593Smuzhiyun Such code doesn't have to follow any of the other rules. 136*4882a593Smuzhiyun 137*4882a593Smuzhiyun3. Each callable function which calls another function must have the 138*4882a593Smuzhiyun correct frame pointer logic, if required by CONFIG_FRAME_POINTER or 139*4882a593Smuzhiyun the architecture's back chain rules. This can by done in asm code 140*4882a593Smuzhiyun with the FRAME_BEGIN/FRAME_END macros. 141*4882a593Smuzhiyun 142*4882a593Smuzhiyun This rule ensures that frame pointer based stack traces will work as 143*4882a593Smuzhiyun designed. If function A doesn't create a stack frame before calling 144*4882a593Smuzhiyun function B, the _caller_ of function A will be skipped on the stack 145*4882a593Smuzhiyun trace. 146*4882a593Smuzhiyun 147*4882a593Smuzhiyun4. Dynamic jumps and jumps to undefined symbols are only allowed if: 148*4882a593Smuzhiyun 149*4882a593Smuzhiyun a) the jump is part of a switch statement; or 150*4882a593Smuzhiyun 151*4882a593Smuzhiyun b) the jump matches sibling call semantics and the frame pointer has 152*4882a593Smuzhiyun the same value it had on function entry. 153*4882a593Smuzhiyun 154*4882a593Smuzhiyun This rule is needed so that objtool can reliably analyze all of a 155*4882a593Smuzhiyun function's code paths. If a function jumps to code in another file, 156*4882a593Smuzhiyun and it's not a sibling call, objtool has no way to follow the jump 157*4882a593Smuzhiyun because it only analyzes a single file at a time. 158*4882a593Smuzhiyun 159*4882a593Smuzhiyun5. A callable function may not execute kernel entry/exit instructions. 160*4882a593Smuzhiyun The only code which needs such instructions is kernel entry code, 161*4882a593Smuzhiyun which shouldn't be be in callable functions anyway. 162*4882a593Smuzhiyun 163*4882a593Smuzhiyun This rule is just a sanity check to ensure that callable functions 164*4882a593Smuzhiyun return normally. 165*4882a593Smuzhiyun 166*4882a593Smuzhiyun 167*4882a593SmuzhiyunObjtool warnings 168*4882a593Smuzhiyun---------------- 169*4882a593Smuzhiyun 170*4882a593SmuzhiyunFor asm files, if you're getting an error which doesn't make sense, 171*4882a593Smuzhiyunfirst make sure that the affected code follows the above rules. 172*4882a593Smuzhiyun 173*4882a593SmuzhiyunFor C files, the common culprits are inline asm statements and calls to 174*4882a593Smuzhiyun"noreturn" functions. See below for more details. 175*4882a593Smuzhiyun 176*4882a593SmuzhiyunAnother possible cause for errors in C code is if the Makefile removes 177*4882a593Smuzhiyun-fno-omit-frame-pointer or adds -fomit-frame-pointer to the gcc options. 178*4882a593Smuzhiyun 179*4882a593SmuzhiyunHere are some examples of common warnings reported by objtool, what 180*4882a593Smuzhiyunthey mean, and suggestions for how to fix them. 181*4882a593Smuzhiyun 182*4882a593Smuzhiyun 183*4882a593Smuzhiyun1. file.o: warning: objtool: func()+0x128: call without frame pointer save/setup 184*4882a593Smuzhiyun 185*4882a593Smuzhiyun The func() function made a function call without first saving and/or 186*4882a593Smuzhiyun updating the frame pointer, and CONFIG_FRAME_POINTER is enabled. 187*4882a593Smuzhiyun 188*4882a593Smuzhiyun If the error is for an asm file, and func() is indeed a callable 189*4882a593Smuzhiyun function, add proper frame pointer logic using the FRAME_BEGIN and 190*4882a593Smuzhiyun FRAME_END macros. Otherwise, if it's not a callable function, remove 191*4882a593Smuzhiyun its ELF function annotation by changing ENDPROC to END, and instead 192*4882a593Smuzhiyun use the manual unwind hint macros in asm/unwind_hints.h. 193*4882a593Smuzhiyun 194*4882a593Smuzhiyun If it's a GCC-compiled .c file, the error may be because the function 195*4882a593Smuzhiyun uses an inline asm() statement which has a "call" instruction. An 196*4882a593Smuzhiyun asm() statement with a call instruction must declare the use of the 197*4882a593Smuzhiyun stack pointer in its output operand. On x86_64, this means adding 198*4882a593Smuzhiyun the ASM_CALL_CONSTRAINT as an output constraint: 199*4882a593Smuzhiyun 200*4882a593Smuzhiyun asm volatile("call func" : ASM_CALL_CONSTRAINT); 201*4882a593Smuzhiyun 202*4882a593Smuzhiyun Otherwise the stack frame may not get created before the call. 203*4882a593Smuzhiyun 204*4882a593Smuzhiyun 205*4882a593Smuzhiyun2. file.o: warning: objtool: .text+0x53: unreachable instruction 206*4882a593Smuzhiyun 207*4882a593Smuzhiyun Objtool couldn't find a code path to reach the instruction. 208*4882a593Smuzhiyun 209*4882a593Smuzhiyun If the error is for an asm file, and the instruction is inside (or 210*4882a593Smuzhiyun reachable from) a callable function, the function should be annotated 211*4882a593Smuzhiyun with the ENTRY/ENDPROC macros (ENDPROC is the important one). 212*4882a593Smuzhiyun Otherwise, the code should probably be annotated with the unwind hint 213*4882a593Smuzhiyun macros in asm/unwind_hints.h so objtool and the unwinder can know the 214*4882a593Smuzhiyun stack state associated with the code. 215*4882a593Smuzhiyun 216*4882a593Smuzhiyun If you're 100% sure the code won't affect stack traces, or if you're 217*4882a593Smuzhiyun a just a bad person, you can tell objtool to ignore it. See the 218*4882a593Smuzhiyun "Adding exceptions" section below. 219*4882a593Smuzhiyun 220*4882a593Smuzhiyun If it's not actually in a callable function (e.g. kernel entry code), 221*4882a593Smuzhiyun change ENDPROC to END. 222*4882a593Smuzhiyun 223*4882a593Smuzhiyun 224*4882a593Smuzhiyun4. file.o: warning: objtool: func(): can't find starting instruction 225*4882a593Smuzhiyun or 226*4882a593Smuzhiyun file.o: warning: objtool: func()+0x11dd: can't decode instruction 227*4882a593Smuzhiyun 228*4882a593Smuzhiyun Does the file have data in a text section? If so, that can confuse 229*4882a593Smuzhiyun objtool's instruction decoder. Move the data to a more appropriate 230*4882a593Smuzhiyun section like .data or .rodata. 231*4882a593Smuzhiyun 232*4882a593Smuzhiyun 233*4882a593Smuzhiyun5. file.o: warning: objtool: func()+0x6: unsupported instruction in callable function 234*4882a593Smuzhiyun 235*4882a593Smuzhiyun This is a kernel entry/exit instruction like sysenter or iret. Such 236*4882a593Smuzhiyun instructions aren't allowed in a callable function, and are most 237*4882a593Smuzhiyun likely part of the kernel entry code. They should usually not have 238*4882a593Smuzhiyun the callable function annotation (ENDPROC) and should always be 239*4882a593Smuzhiyun annotated with the unwind hint macros in asm/unwind_hints.h. 240*4882a593Smuzhiyun 241*4882a593Smuzhiyun 242*4882a593Smuzhiyun6. file.o: warning: objtool: func()+0x26: sibling call from callable instruction with modified stack frame 243*4882a593Smuzhiyun 244*4882a593Smuzhiyun This is a dynamic jump or a jump to an undefined symbol. Objtool 245*4882a593Smuzhiyun assumed it's a sibling call and detected that the frame pointer 246*4882a593Smuzhiyun wasn't first restored to its original state. 247*4882a593Smuzhiyun 248*4882a593Smuzhiyun If it's not really a sibling call, you may need to move the 249*4882a593Smuzhiyun destination code to the local file. 250*4882a593Smuzhiyun 251*4882a593Smuzhiyun If the instruction is not actually in a callable function (e.g. 252*4882a593Smuzhiyun kernel entry code), change ENDPROC to END and annotate manually with 253*4882a593Smuzhiyun the unwind hint macros in asm/unwind_hints.h. 254*4882a593Smuzhiyun 255*4882a593Smuzhiyun 256*4882a593Smuzhiyun7. file: warning: objtool: func()+0x5c: stack state mismatch 257*4882a593Smuzhiyun 258*4882a593Smuzhiyun The instruction's frame pointer state is inconsistent, depending on 259*4882a593Smuzhiyun which execution path was taken to reach the instruction. 260*4882a593Smuzhiyun 261*4882a593Smuzhiyun Make sure that, when CONFIG_FRAME_POINTER is enabled, the function 262*4882a593Smuzhiyun pushes and sets up the frame pointer (for x86_64, this means rbp) at 263*4882a593Smuzhiyun the beginning of the function and pops it at the end of the function. 264*4882a593Smuzhiyun Also make sure that no other code in the function touches the frame 265*4882a593Smuzhiyun pointer. 266*4882a593Smuzhiyun 267*4882a593Smuzhiyun Another possibility is that the code has some asm or inline asm which 268*4882a593Smuzhiyun does some unusual things to the stack or the frame pointer. In such 269*4882a593Smuzhiyun cases it's probably appropriate to use the unwind hint macros in 270*4882a593Smuzhiyun asm/unwind_hints.h. 271*4882a593Smuzhiyun 272*4882a593Smuzhiyun 273*4882a593Smuzhiyun8. file.o: warning: objtool: funcA() falls through to next function funcB() 274*4882a593Smuzhiyun 275*4882a593Smuzhiyun This means that funcA() doesn't end with a return instruction or an 276*4882a593Smuzhiyun unconditional jump, and that objtool has determined that the function 277*4882a593Smuzhiyun can fall through into the next function. There could be different 278*4882a593Smuzhiyun reasons for this: 279*4882a593Smuzhiyun 280*4882a593Smuzhiyun 1) funcA()'s last instruction is a call to a "noreturn" function like 281*4882a593Smuzhiyun panic(). In this case the noreturn function needs to be added to 282*4882a593Smuzhiyun objtool's hard-coded global_noreturns array. Feel free to bug the 283*4882a593Smuzhiyun objtool maintainer, or you can submit a patch. 284*4882a593Smuzhiyun 285*4882a593Smuzhiyun 2) funcA() uses the unreachable() annotation in a section of code 286*4882a593Smuzhiyun that is actually reachable. 287*4882a593Smuzhiyun 288*4882a593Smuzhiyun 3) If funcA() calls an inline function, the object code for funcA() 289*4882a593Smuzhiyun might be corrupt due to a gcc bug. For more details, see: 290*4882a593Smuzhiyun https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70646 291*4882a593Smuzhiyun 292*4882a593Smuzhiyun9. file.o: warning: objtool: funcA() call to funcB() with UACCESS enabled 293*4882a593Smuzhiyun 294*4882a593Smuzhiyun This means that an unexpected call to a non-whitelisted function exists 295*4882a593Smuzhiyun outside of arch-specific guards. 296*4882a593Smuzhiyun X86: SMAP (stac/clac): __uaccess_begin()/__uaccess_end() 297*4882a593Smuzhiyun ARM: PAN: uaccess_enable()/uaccess_disable() 298*4882a593Smuzhiyun 299*4882a593Smuzhiyun These functions should be called to denote a minimal critical section around 300*4882a593Smuzhiyun access to __user variables. See also: https://lwn.net/Articles/517475/ 301*4882a593Smuzhiyun 302*4882a593Smuzhiyun The intention of the warning is to prevent calls to funcB() from eventually 303*4882a593Smuzhiyun calling schedule(), potentially leaking the AC flags state, and not 304*4882a593Smuzhiyun restoring them correctly. 305*4882a593Smuzhiyun 306*4882a593Smuzhiyun It also helps verify that there are no unexpected calls to funcB() which may 307*4882a593Smuzhiyun access user space pages with protections against doing so disabled. 308*4882a593Smuzhiyun 309*4882a593Smuzhiyun To fix, either: 310*4882a593Smuzhiyun 1) remove explicit calls to funcB() from funcA(). 311*4882a593Smuzhiyun 2) add the correct guards before and after calls to low level functions like 312*4882a593Smuzhiyun __get_user_size()/__put_user_size(). 313*4882a593Smuzhiyun 3) add funcB to uaccess_safe_builtin whitelist in tools/objtool/check.c, if 314*4882a593Smuzhiyun funcB obviously does not call schedule(), and is marked notrace (since 315*4882a593Smuzhiyun function tracing inserts additional calls, which is not obvious from the 316*4882a593Smuzhiyun sources). 317*4882a593Smuzhiyun 318*4882a593Smuzhiyun10. file.o: warning: func()+0x5c: stack layout conflict in alternatives 319*4882a593Smuzhiyun 320*4882a593Smuzhiyun This means that in the use of the alternative() or ALTERNATIVE() 321*4882a593Smuzhiyun macro, the code paths have conflicting modifications to the stack. 322*4882a593Smuzhiyun The problem is that there is only one ORC unwind table, which means 323*4882a593Smuzhiyun that the ORC unwind entries must be consistent for all possible 324*4882a593Smuzhiyun instruction boundaries regardless of which code has been patched. 325*4882a593Smuzhiyun This limitation can be overcome by massaging the alternatives with 326*4882a593Smuzhiyun NOPs to shift the stack changes around so they no longer conflict. 327*4882a593Smuzhiyun 328*4882a593Smuzhiyun11. file.o: warning: unannotated intra-function call 329*4882a593Smuzhiyun 330*4882a593Smuzhiyun This warning means that a direct call is done to a destination which 331*4882a593Smuzhiyun is not at the beginning of a function. If this is a legit call, you 332*4882a593Smuzhiyun can remove this warning by putting the ANNOTATE_INTRA_FUNCTION_CALL 333*4882a593Smuzhiyun directive right before the call. 334*4882a593Smuzhiyun 335*4882a593Smuzhiyun 336*4882a593SmuzhiyunIf the error doesn't seem to make sense, it could be a bug in objtool. 337*4882a593SmuzhiyunFeel free to ask the objtool maintainer for help. 338*4882a593Smuzhiyun 339*4882a593Smuzhiyun 340*4882a593SmuzhiyunAdding exceptions 341*4882a593Smuzhiyun----------------- 342*4882a593Smuzhiyun 343*4882a593SmuzhiyunIf you _really_ need objtool to ignore something, and are 100% sure 344*4882a593Smuzhiyunthat it won't affect kernel stack traces, you can tell objtool to 345*4882a593Smuzhiyunignore it: 346*4882a593Smuzhiyun 347*4882a593Smuzhiyun- To skip validation of a function, use the STACK_FRAME_NON_STANDARD 348*4882a593Smuzhiyun macro. 349*4882a593Smuzhiyun 350*4882a593Smuzhiyun- To skip validation of a file, add 351*4882a593Smuzhiyun 352*4882a593Smuzhiyun OBJECT_FILES_NON_STANDARD_filename.o := y 353*4882a593Smuzhiyun 354*4882a593Smuzhiyun to the Makefile. 355*4882a593Smuzhiyun 356*4882a593Smuzhiyun- To skip validation of a directory, add 357*4882a593Smuzhiyun 358*4882a593Smuzhiyun OBJECT_FILES_NON_STANDARD := y 359*4882a593Smuzhiyun 360*4882a593Smuzhiyun to the Makefile. 361