xref: /aosp_15_r20/external/AFLplusplus/instrumentation/README.instrument_list.md (revision 08b48e0b10e97b33e7b60c5b6e2243bd915777f2)
1# Using AFL++ with partial instrumentation
2
3This file describes two different mechanisms to selectively instrument only
4specific parts in the target.
5
6Both mechanisms work for LLVM and GCC_PLUGIN, but not for afl-clang/afl-gcc.
7
8## 1) Description and purpose
9
10When building and testing complex programs where only a part of the program is
11the fuzzing target, it often helps to only instrument the necessary parts of the
12program, leaving the rest uninstrumented. This helps to focus the fuzzer on the
13important parts of the program, avoiding undesired noise and disturbance by
14uninteresting code being exercised.
15
16For this purpose, "partial instrumentation" support is provided by AFL++ that
17allows to specify what should be instrumented and what not.
18
19Both mechanisms for partial instrumentation can be used together.
20
21## 2) Selective instrumentation with __AFL_COVERAGE_... directives
22
23In this mechanism, the selective instrumentation is done in the source code.
24
25After the includes, a special define has to be made, e.g.:
26
27```
28#include <stdio.h>
29#include <stdint.h>
30// ...
31
32__AFL_COVERAGE();  // <- required for this feature to work
33```
34
35If you want to disable the coverage at startup until you specify coverage should
36be started, then add `__AFL_COVERAGE_START_OFF();` at that position.
37
38From here on out, you have the following macros available that you can use in
39any function where you want:
40
41* `__AFL_COVERAGE_ON();` - Enable coverage from this point onwards.
42* `__AFL_COVERAGE_OFF();` - Disable coverage from this point onwards.
43* `__AFL_COVERAGE_DISCARD();` - Reset all coverage gathered until this point.
44* `__AFL_COVERAGE_SKIP();` - Mark this test case as unimportant. Whatever
45  happens, afl-fuzz will ignore it.
46
47A special function is `__afl_coverage_interesting`. To use this, you must define
48`void __afl_coverage_interesting(u8 val, u32 id);`. Then you can use this
49function globally, where the `val` parameter can be set by you, the `id`
50parameter is for afl-fuzz and will be overwritten. Note that useful parameters
51for `val` are: 1, 2, 3, 4, 8, 16, 32, 64, 128. A value of, e.g., 33 will be seen
52as 32 for coverage purposes.
53
54## 3) Selective instrumentation with AFL_LLVM_ALLOWLIST/AFL_LLVM_DENYLIST
55
56This feature is equivalent to llvm 12 sancov feature and allows to specify on a
57filename and/or function name level to instrument these or skip them.
58
59### 3a) How to use the partial instrumentation mode
60
61In order to build with partial instrumentation, you need to build with
62afl-clang-fast/afl-clang-fast++ or afl-clang-lto/afl-clang-lto++. The only
63required change is that you need to set either the environment variable
64`AFL_LLVM_ALLOWLIST` or `AFL_LLVM_DENYLIST` set with a filename.
65
66That file should contain the file names or functions that are to be instrumented
67(`AFL_LLVM_ALLOWLIST`) or are specifically NOT to be instrumented
68(`AFL_LLVM_DENYLIST`).
69
70GCC_PLUGIN: you can use either `AFL_LLVM_ALLOWLIST` or `AFL_GCC_ALLOWLIST` (or
71the same for `_DENYLIST`), both work.
72
73For matching to succeed, the function/file name that is being compiled must end
74in the function/file name entry contained in this instrument file list. That is
75to avoid breaking the match when absolute paths are used during compilation.
76
77**NOTE:** In builds with optimization enabled, functions might be inlined and
78would not match!
79
80For example, if your source tree looks like this:
81
82```
83project/
84project/feature_a/a1.cpp
85project/feature_a/a2.cpp
86project/feature_b/b1.cpp
87project/feature_b/b2.cpp
88```
89
90And you only want to test feature_a, then create an "instrument file list" file
91containing:
92
93```
94feature_a/a1.cpp
95feature_a/a2.cpp
96```
97
98However, if the "instrument file list" file contains only this, it works as
99well:
100
101```
102a1.cpp
103a2.cpp
104```
105
106But it might lead to files being unwantedly instrumented if the same filename
107exists somewhere else in the project directories.
108
109You can also specify function names. Note that for C++ the function names must
110be mangled to match! `nm` can print these names.
111
112AFL++ is able to identify whether an entry is a filename or a function. However,
113if you want to be sure (and compliant to the sancov allow/blocklist format), you
114can specify source file entries like this:
115
116```
117src: *malloc.c
118```
119
120And function entries like this:
121
122```
123fun: MallocFoo
124```
125
126Note that whitespace is ignored and comments (`# foo`) are supported.
127
128### 3b) UNIX-style pattern matching
129
130You can add UNIX-style pattern matching in the "instrument file list" entries.
131See `man fnmatch` for the syntax. Do not set any of the `fnmatch` flags.