Currently syzkaller uses per-call basic block (BB) coverage.
This change implements edge (not-per-call) coverage.
Edge coverage is more detailed than BB coverage as it captures
not-taken branches, looping, etc. So it provides better feedback signal.
This coverage is now called "signal" throughout the code.
BB code coverage is also collected as it is required for visualisation.
Not doing per-call coverage reduces corpus ~6-7x (from ~35K to ~5K),
this has profound effect on fuzzing efficiency.
A bunch of spot optmizations after cpu/memory profiling:
1. Optimize hot-path coverage comparison in fuzzer.
2. Don't allocate and copy serialized program, serialize directly into shmem.
3. Reduce allocations during parsing of output shmem (encoding/binary sucks).
4. Don't allocate and copy coverage arrays, refer directly to the shmem region
(we are not going to mutate them).
5. Don't validate programs outside of tests, validation allocates tons of memory.
6. Replace the choose primitive with simpler switches.
Choose allocates fullload of memory (for int, func, and everything the func refers).
7. Other minor optimizations.
When executors send coverage data to the manager, they clamp the addresses
of covered blocks to 32 bits. Manager uses RestorePC() to restore the original
addresses.
Previously, RestorePC() assumed that the upper 4 bytes of a kernel code
address were 0xffffffff, which is not so on Android.
Instead we now parse `readelf -SW vmlinux` output to obtain the upper bytes of
PROGBITS sections VMAs in the case those VMAs are non-zero. We assume that
the upper 4 bytes are the same for every section.