Skip to content

Commit 14947b3

Browse files
Add AFL++ integration (#379)
The patch implements the required APIs and infra to build Grammarinator-driven custom AFL++ mutators. Beside the basic integration tasks, Grammarinator is extended with SubTreePool population support, custom ddmin-based trimming for AFL and two new mutators based on the new population approach.
1 parent 3d78c7c commit 14947b3

File tree

14 files changed

+1312
-63
lines changed

14 files changed

+1312
-63
lines changed

grammarinator-cxx/CMakeLists.txt

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright (c) 2025 Renata Hodovan, Akos Kiss.
1+
# Copyright (c) 2025-2026 Renata Hodovan, Akos Kiss.
22
#
33
# Licensed under the BSD 3-Clause License
44
# <LICENSE.rst or https://opensource.org/licenses/BSD-3-Clause>.
@@ -12,6 +12,7 @@ option(GRAMMARINATOR_GENERATE "build generator tool" OFF)
1212
option(GRAMMARINATOR_DECODE "build decoder tool" OFF)
1313
option(GRAMMARINATOR_FUZZNULL "build fuzznull tool" OFF)
1414
option(GRAMMARINATOR_GRLF "build libgrlf" OFF)
15+
option(GRAMMARINATOR_GRAFL "build libgrafl" OFF)
1516

1617
set(GRAMMARINATOR_GENERATOR "" CACHE STRING "name of the generator class created by grammarinator-process (mandatory for specialized artefacts)")
1718
set(GRAMMARINATOR_MODEL "" CACHE STRING "name of the decision model class (for specialized artefacts)")
@@ -71,8 +72,9 @@ grammarinator_status(GRAMMARINATOR_GENERATE)
7172
grammarinator_status(GRAMMARINATOR_DECODE)
7273
grammarinator_status(GRAMMARINATOR_FUZZNULL)
7374
grammarinator_status(GRAMMARINATOR_GRLF)
75+
grammarinator_status(GRAMMARINATOR_GRAFL)
7476

75-
if(GRAMMARINATOR_GENERATE OR GRAMMARINATOR_DECODE OR GRAMMARINATOR_FUZZNULL OR GRAMMARINATOR_GRLF)
77+
if(GRAMMARINATOR_GENERATE OR GRAMMARINATOR_DECODE OR GRAMMARINATOR_FUZZNULL OR GRAMMARINATOR_GRLF OR GRAMMARINATOR_GRAFL)
7678
if ("${GRAMMARINATOR_SUFFIX}" STREQUAL "")
7779
set(GRAMMARINATOR_SUFFIX "${GRAMMARINATOR_GENERATOR}")
7880
string(TOLOWER "${GRAMMARINATOR_SUFFIX}" GRAMMARINATOR_SUFFIX)
@@ -126,6 +128,9 @@ add_subdirectory(libgrammarinator)
126128
if(GRAMMARINATOR_GRLF)
127129
add_subdirectory(libgrlf)
128130
endif()
131+
if(GRAMMARINATOR_GRAFL)
132+
add_subdirectory(libgrafl)
133+
endif()
129134
if(GRAMMARINATOR_GENERATE OR GRAMMARINATOR_DECODE OR GRAMMARINATOR_FUZZNULL)
130135
add_subdirectory(tools)
131136
endif()

grammarinator-cxx/dev/build.py

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,21 +31,25 @@ def build_options_append(cmakeopt, cliarg):
3131
build_options_append('GRAMMARINATOR_DECODE', 'ON' if args.decode else 'OFF')
3232
build_options_append('GRAMMARINATOR_FUZZNULL', 'ON' if args.fuzznull else 'OFF')
3333
build_options_append('GRAMMARINATOR_GRLF', 'ON' if args.grlf else 'OFF')
34+
build_options_append('GRAMMARINATOR_GRAFL', 'ON' if args.grafl else 'OFF')
3435

35-
if args.generate or args.fuzznull or args.grlf:
36+
if args.generate or args.fuzznull or args.grlf or args.grafl:
3637
build_options_append('GRAMMARINATOR_GENERATOR', args.generator)
3738
build_options_append('GRAMMARINATOR_MODEL', args.model)
3839
build_options_append('GRAMMARINATOR_LISTENER', args.listener)
3940
build_options_append('GRAMMARINATOR_TRANSFORMER', args.transformer)
4041

41-
if args.generate or args.decode or args.fuzznull or args.grlf:
42+
if args.generate or args.decode or args.fuzznull or args.grlf or args.grafl:
4243
build_options_append('GRAMMARINATOR_SERIALIZER', args.serializer)
4344
build_options_append('GRAMMARINATOR_TREECODEC', args.treecodec)
4445
build_options_append('GRAMMARINATOR_INCLUDE', args.include)
4546
build_options_append('GRAMMARINATOR_INCLUDEDIRS', ';'.join(os.path.abspath(includedir) for includedir in args.includedir))
4647
build_options_append('GRAMMARINATOR_SUFFIX', args.suffix)
4748
build_options_append('GRAMMARINATOR_LOG_LEVEL', args.log_level)
4849

50+
if args.grafl:
51+
build_options_append('GRAMMARINATOR_AFL_INCLUDEDIR', os.path.abspath(args.afl_includedir))
52+
4953
return build_options
5054

5155

@@ -109,6 +113,10 @@ def main():
109113
help='build a dummy fuzznull binary to test libFuzzer integration without a real fuzz target (default: %(default)s)')
110114
sgrp.add_argument('--grlf', default=False, action='store_true',
111115
help='build a static libgrlf library for libFuzzer integration (default: %(default)s)')
116+
sgrp.add_argument('--grafl', default=False, action='store_true',
117+
help='build a shared libgrafl library for AFL++ integration (default: %(default)s)')
118+
sgrp.add_argument('--afl-includedir', metavar='DIR',
119+
help='AFL include directory (mandatory if --grafl is specified)')
112120
sgrp.add_argument('--generator', metavar='NAME',
113121
help='name of the generator class')
114122
sgrp.add_argument('--model', metavar='NAME',
@@ -134,12 +142,16 @@ def main():
134142
'json': 'JsonTreeCodec'
135143
}[args.tree_format] if args.tree_format else None
136144

137-
if args.generate or args.fuzznull or args.grlf:
145+
if args.generate or args.fuzznull or args.grlf or args.grafl:
138146
if not args.includedir or (not args.generator and not args.include):
139147
parser.error('To build specialized artefacts, either the `--generator` or the `--include`, and the `--includedir` arguments must be defined.')
140148
if not args.generator and not args.suffix:
141149
sys.stderr.write(f'{parser.prog}: Neither `--generator` nor `--suffix` is defined; the created binary will get a default name.\n')
142150

151+
if args.grafl:
152+
if not args.afl_includedir:
153+
parser.error('To build AFL integration, the `--afl-includedir` argument must be defined.')
154+
143155
try:
144156
configure_cmake(args)
145157
cmake_build(args)
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Copyright (c) 2025-2026 Renata Hodovan, Akos Kiss.
2+
#
3+
# Licensed under the BSD 3-Clause License
4+
# <LICENSE.rst or https://opensource.org/licenses/BSD-3-Clause>.
5+
# This file may not be copied, modified, or distributed except
6+
# according to those terms.
7+
8+
grammarinator_spec_target_name(GRAFL grafl)
9+
add_library(${GRAFL} SHARED grafl.cpp)
10+
if(NOT DEFINED GRAMMARINATOR_AFL_INCLUDEDIR)
11+
message(FATAL_ERROR "GRAMMARINATOR_AFL_INCLUDEDIR not set.")
12+
endif()
13+
target_include_directories(${GRAFL} PRIVATE ${GRAMMARINATOR_AFL_INCLUDEDIR})
14+
grammarinator_spec_definitions(${GRAFL})
15+
target_link_libraries(${GRAFL} PRIVATE grammarinator)
16+
17+
configure_file(libgrafl.pc.in lib${GRAFL}.pc @ONLY)
18+
19+
install(TARGETS ${GRAFL} DESTINATION lib)
20+
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/lib${GRAFL}.pc DESTINATION lib/pkgconfig)
21+
22+
set(GRAFL ${GRAFL} PARENT_SCOPE)

0 commit comments

Comments
 (0)