Hi Kcc, I'm trying enabling the Asan in my firmware, but I find the asan instrumentation code size impact is too big for me. I just implement necessary firmware version runtime library functions (e.g. __asan_report_load8) with blank body firstly to pass the asan enabled build, but I find the new binary code size is already ~2.5 times as original one with asan disabled in GCC. I know Linux kernel already enabled the asan (a.k.a Kasan), and is there any magic of asan for Linux to control its code size impact? Please advise how to mitigate the asan code size overhead. Steven Shi Intel\SSG\STO\UEFI Firmware Tel: +86 021-61166522 iNet: 821-6522 -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20161026/720d5810/attachment.html>
On Wed, Oct 26, 2016 at 7:42 AM, Shi, Steven <steven.shi at intel.com> wrote:> Hi Kcc, > > I’m trying enabling the Asan in my firmware, but I find the asan > instrumentation code size impact is too big for me. I just implement > necessary firmware version runtime library functions (e.g. > __asan_report_load8) with blank body firstly to pass the asan enabled > build, but I find the new binary code size is already ~2.5 times as > original one with asan disabled in GCC. I know Linux kernel already enabled > the asan (a.k.a Kasan), and is there any magic of asan for Linux to control > its code size impact? >I don't think there is much magic.> Please advise how to mitigate the asan code size overhead. >First, need to figure out what parts of instrumentation increase the code size the most. Start from switching from inline instrumentation to instrumentation with calls: With Clang that is "-mllvm -asan-instrumentation-with-call-threshold=0", gcc should have something similar. W/o this flag the instrumentation will look like this: .cfi_def_cfa_offset 16 movq %rdi, %rax shrq $3, %rax movb 2147450880(%rax), %al testb %al, %al jne .LBB0_1 .LBB0_3: movl (%rdi), %eax popq %rcx retq .LBB0_1: movl %edi, %ecx andl $7, %ecx addl $3, %ecx cmpb %al, %cl jl .LBB0_3 # BB#2: callq __asan_report_load4 With this flag it will look like this: movq %rdi, %rbx callq __asan_load4 movl (%rbx), %eax Obviously, there is a cost in performance. Clang (and recent gcc) also have a convenience flag -fsanitize=kernel-address: movq %rdi, %rbx callq __asan_load4_noabort movl (%rbx), %eax If that does not solve your code size problem, let's look at it more. --kcc> > > > > *Steven Shi* > > *Intel\SSG\STO\UEFI Firmware* > > > > Tel: +86 021-61166522 <+86%2021%206116%206522> > > iNet: 821-6522 > > >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20161026/cf1e3834/attachment.html>
Hi Kcc, Thank your advices.>Start from switching from inline instrumentation to instrumentation with calls: >With Clang that is "-mllvm -asan-instrumentation-with-call-threshold=0", gcc should have something similar.I see the call-threshold option force to use the calls and have same effect as -fsanitize=kernel-address in below code. Thanks. http://llvm.org/svn/llvm-project/llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp line 1956: bool UseCalls CompileKernel || (ClInstrumentationWithCallsThreshold >= 0 && ToInstrument.size() > (unsigned)ClInstrumentationWithCallsThreshold);>Obviously, there is a cost in performance.The call cost to my firmware should be very low. (1) Not like CPU-intensive application, my firmware is an IO-intensive software, the boot performance bottleneck is usually because of slow IO response. If Asan instrumentation mainly bring overhead to CPU, it is not a big problem to my firmware. (2) Not like memory-intensive application, my firmware usually have sufficient system memory to use. If Asan mainly bring overhead to system memory consumption for shadow memory metadata, it is not a big problem for me too. But my firmware usually care the code size, even in debug version. If my Asan-enabled firmware image size is too big, I cannot easily apply and run it on real HW.>Clang (and recent gcc) also have a convenience flag -fsanitize=kernel-address: > movq %rdi, %rbx > callq __asan_load4_noabort > movl (%rbx), %eaxI like the -fsanitize=kernel-address option, and I believe it better fit my firmware scenario rather than -fsanitize=address. I but after take a look at the current LLVM Asan implementation, I have some concerns that kernel-address might disable the global and stack instrumentations by default as below code. Does LLVM Asan really support -fsanitize=kernel-address to check glabal and stack buffer issues? http://llvm.org/svn/llvm-project/llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp line 1723: // TODO(glider): temporarily disabled globals instrumentation for KASan. if (ClGlobals && !CompileKernel) { Function *CtorFunc = M.getFunction(kAsanModuleCtorName); assert(CtorFunc); IRBuilder<> IRB(CtorFunc->getEntryBlock().getTerminator()); Changed |= InstrumentGlobals(IRB, M); } Line2287: bool DoStackMalloc = ClUseAfterReturn && !ASan.CompileKernel && LocalStackSize <= kMaxStackMallocSize; Thanks Steven -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20161102/2bf3d6bb/attachment.html>