Browse Source

native_simulator: Rework fuzzing support

The fuzzing support in the native_simulator had not got
to work yet. Let's remove it, and instead let the
test application handle it.

For this we make public the functions which initialize
the simulation and advance time, so the fuzzing tests
can use it.

Signed-off-by: Alberto Escolar Piedras <alberto.escolar.piedras@nordicsemi.no>
pull/72263/head
Alberto Escolar Piedras 1 year ago committed by Johan Hedberg
parent
commit
09d554b769
  1. 36
      scripts/native_simulator/common/src/include/nsi_main_semipublic.h
  2. 47
      scripts/native_simulator/common/src/main.c

36
scripts/native_simulator/common/src/include/nsi_main_semipublic.h

@ -0,0 +1,36 @@ @@ -0,0 +1,36 @@
/*
* Copyright (c) 2024 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef NSI_COMMON_SRC_INCL_NSI_MAIN_SEMIPUBLIC_H
#define NSI_COMMON_SRC_INCL_NSI_MAIN_SEMIPUBLIC_H
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/*
* These APIs are exposed for special use cases in which a developer needs to
* replace the native simulator main loop.
* An example of such a case is LLVMs fuzzing support. For this one sets
* NSI_NO_MAIN, and provides an specialized main() or hooks into the tooling
* provided main().
*
* These APIs should be used with care, and not be used when the native
* simulator main() is built in.
*
* Check nsi_main.c for more information.
*/
void nsi_init(int argc, char *argv[]);
void nsi_exec_for(uint64_t us);
#ifdef __cplusplus
}
#endif
#endif /* NSI_COMMON_SRC_INCL_NSI_MAIN_SEMIPUBLIC_H */

47
scripts/native_simulator/common/src/main.c

@ -52,9 +52,11 @@ NSI_FUNC_NORETURN void nsi_exit(int exit_code) @@ -52,9 +52,11 @@ NSI_FUNC_NORETURN void nsi_exit(int exit_code)
/**
* Run all early native simulator initialization steps, including command
* line parsing and CPU start, until we are ready to let the HW models
* run via hwm_one_event()
* run via nsi_hws_one_event()
*
* Note: This API should normally only be called by the native simulator main()
*/
static void nsi_init(int argc, char *argv[])
void nsi_init(int argc, char *argv[])
{
/*
* Let's ensure that even if we are redirecting to a file, we get stdout
@ -92,6 +94,8 @@ static void nsi_init(int argc, char *argv[]) @@ -92,6 +94,8 @@ static void nsi_init(int argc, char *argv[])
* return. Note that this does not affect event timing, so the "next
* event" may be significantly after the request if the hardware has
* not been configured to e.g. send an interrupt when expected.
*
* Note: This API should normally only be called by the native simulator main()
*/
void nsi_exec_for(uint64_t us)
{
@ -102,7 +106,7 @@ void nsi_exec_for(uint64_t us) @@ -102,7 +106,7 @@ void nsi_exec_for(uint64_t us)
} while (nsi_hws_get_time() < (start + us));
}
#ifndef NSI_LIBFUZZER
#ifndef NSI_NO_MAIN
/**
*
@ -121,39 +125,4 @@ int main(int argc, char *argv[]) @@ -121,39 +125,4 @@ int main(int argc, char *argv[])
return 1; /* LCOV_EXCL_LINE */
}
#else /* NSI_LIBFUZZER */
/**
* Entry point for fuzzing (when enabled). Works by placing the data
* into two known symbols, triggering an app-visible interrupt, and
* then letting the simulator run for a fixed amount of time (intended to be
* "long enough" to handle the event and reach a quiescent state
* again)
*/
uint8_t *nsi_fuzz_buf, nsi_fuzz_sz;
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t sz)
{
static bool nsi_initialized;
if (!nsi_initialized) {
nsi_init(0, NULL);
nsi_initialized = true;
}
/* Provide the fuzz data to the embedded OS as an interrupt, with
* "DMA-like" data placed into nsi_fuzz_buf/sz
*/
nsi_fuzz_buf = (void *)data;
nsi_fuzz_sz = sz;
hw_irq_ctrl_set_irq(NSI_FUZZ_IRQ);
/* Give the OS time to process whatever happened in that
* interrupt and reach an idle state.
*/
nsi_exec_for(NSI_FUZZ_TIME);
return 0;
}
#endif /* NSI_LIBFUZZER */
#endif /* NSI_NO_MAIN */

Loading…
Cancel
Save