- Notifications
You must be signed in to change notification settings - Fork1.1k
AddressSanitizerZeroBasedShadow
To enable this mode, buildall the sources with-fsanitize-address-zero-base-shadow, clang-only.
Instead of computingShadow = (Mem >> 3) + kOffset we computeShadow = (Mem >> 3), i.e.kOffset = 0 (seeAddressSanitizerAlgorithm).This mode is possible only if 1/8 of address space starting from the zero page is not occupied at startup andAddressSanitizer can map it for the shadow.We are aware of only one situation where this works: Linux executables compiled with-fPIC or-fPIE and linked with-pie.
% cat procmaps.cc #include <unistd.h>#include <stdio.h>#include <stdlib.h>int main() { char buff[100]; sprintf(buff, "cat /proc/%d/maps", getpid()); system(buff);}Regular mode:
% clang -fsanitize=address ./procmaps.cc && ./a.out 00400000-00421000 r-xp 00000000 fc:00 1573310 /tmp/a.out00620000-00621000 r--p 00020000 fc:00 1573310 /tmp/a.out00621000-00622000 rw-p 00021000 fc:00 1573310 /tmp/a.out00622000-0338e000 rw-p 00000000 00:00 0 ffffffff000-120000000000 rw-p 00000000 00:00 0 <<<<<<<<<<< LowShadow120000000000-140000000000 ---p 00000000 00:00 0 <<<<<<<<< SHadowGap140000000000-200000000000 rw-p 00000000 00:00 0 <<<<<<<<< HighShadow7f1ebd5a9000-7f1ebd75e000 r-xp 00000000 fc:00 1208459 /lib/x86_64-linux-gnu/libc-2.15.so....7f1ebe1c2000-7f1ebe1c4000 rw-p 00023000 fc:00 1208920 /lib/x86_64-linux-gnu/ld-2.15.so7fffccd4b000-7fffccd6c000 rw-p 00000000 00:00 0 [stack]7fffccdff000-7fffcce00000 r-xp 00000000 00:00 0 [vdso]Zero shadow offset mode (with -pie):
% clang -fsanitize=address -fsanitize-address-zero-base-shadow -fPIE -pie ./procmaps.cc && ./a.out 00040000-20000000000 ---p 00000000 00:00 0 <<<<<<<<< ShadowGap20000000000-100000000000 rw-p 00000000 00:00 0 <<<<<<<<< HighShadow7f343283c000-7f34329f1000 r-xp 00000000 fc:00 1208459 /lib/x86_64-linux-gnu/libc-2.15.so7f3433679000-7f343367a000 rw-p 00022000 fc:00 1573310 /tmp/a.out7f343367a000-7f34363e6000 rw-p 00000000 00:00 0 7fff79e32000-7fff79e53000 rw-p 00000000 00:00 0 [stack]7fff79f1a000-7fff79f1b000 r-xp 00000000 00:00 0 [vdso]Why is this worth the trouble?Zero shadow offset not just saves one arithmetic instruction,but also saves one register, which is otherwise occupied with the large constant. Compare these two:
% cat load.c long Foo(long *a) { return *a; }% clang -fsanitize=address -fsanitize-address-zero-base-shadow -O2 -c load.c && objdump -d load.o0000000000000000 <Foo>: 0:50 push %rax 1:48 89 f8 mov %rdi,%rax 4:48 c1 e8 03 shr $0x3,%rax 8:80 38 00 cmpb $0x0,(%rax) b:75 05 jne 12 <Foo+0x12> d:48 8b 07 mov (%rdi),%rax 10:5a pop %rdx% clang -fsanitize=address -O2 -c load.c && objdump -d load.o0000000000000000 <Foo>: 0:50 push %rax 1:48 89 f8 mov %rdi,%rax 4:48 c1 e8 03 shr $0x3,%rax 8:48 b9 00 00 00 00 00 movabs $0x100000000000,%rcx f:10 00 00 12:48 09 c1 or %rax,%rcx 15:80 39 00 cmpb $0x0,(%rcx) 18:75 05 jne 1f <Foo+0x1f> 1a:48 8b 07 mov (%rdi),%rax 1d:5a pop %rdx 1e:c3 retqThe data below reflects the performance gain from zero-based shadow on SPEC CPU 2006.Measured LLVM r174590 (on Google Code) on Intel Xeon W3690 @3.47GHz
400.perlbench, 1200.00, 1179.00, 0.98 401.bzip2, 885.00, 821.00, 0.93 403.gcc, 744.00, 724.00, 0.97 429.mcf, 605.00, 579.00, 0.96 445.gobmk, 843.00, 809.00, 0.96 456.hmmer, 1305.00, 1236.00, 0.95 458.sjeng, 923.00, 898.00, 0.97 462.libquantum, 539.00, 532.00, 0.99 464.h264ref, 1269.00, 1194.00, 0.94 471.omnetpp, 629.00, 598.00, 0.95 473.astar, 676.00, 663.00, 0.98 483.xalancbmk, 493.00, 452.00, 0.92 433.milc, 712.00, 656.00, 0.92 444.namd, 637.00, 592.00, 0.93 447.dealII, 654.00, 631.00, 0.96 450.soplex, 391.00, 369.00, 0.94 453.povray, 458.00, 419.00, 0.91 470.lbm, 388.00, 384.00, 0.99 482.sphinx3, 995.00, 886.00, 0.89We are experimenting with another way to achieve zero-based offset using-Wl,-Ttext-segment=0x40000000.TODO