From 1bcb0f2cfb7c30ad29d7264ae8d5bf84bbecf805 Mon Sep 17 00:00:00 2001 From: "Corteggiani, Nassim" Date: Tue, 27 Aug 2024 15:30:53 +0200 Subject: [PATCH] Observer for fsdb traces --- libpresifuzz_observers/Cargo.toml | 3 +- libpresifuzz_observers/build.rs | 15 +- libpresifuzz_observers/src/lib.rs | 1 + libpresifuzz_observers/src/npi_c.c | 265 +++++++++++++++++-- libpresifuzz_observers/src/trace_observer.rs | 34 +-- 5 files changed, 283 insertions(+), 35 deletions(-) diff --git a/libpresifuzz_observers/Cargo.toml b/libpresifuzz_observers/Cargo.toml index 0203429..53549f3 100644 --- a/libpresifuzz_observers/Cargo.toml +++ b/libpresifuzz_observers/Cargo.toml @@ -25,6 +25,7 @@ build = "build.rs" [build-dependencies] cc = "1" +bindgen = "0.64" [dependencies] clap = { version = "3.2", features = ["default"] } @@ -47,4 +48,4 @@ rand = "0.8.5" tempfile = "3.9.0" flate2 = "1.0" quick-xml = "0.32.0" -regex = "1" \ No newline at end of file +regex = "1" diff --git a/libpresifuzz_observers/build.rs b/libpresifuzz_observers/build.rs index 60404e7..ba80b23 100644 --- a/libpresifuzz_observers/build.rs +++ b/libpresifuzz_observers/build.rs @@ -5,7 +5,11 @@ use std::path::Path; use std::env; +extern crate bindgen; +use std::path::PathBuf; + fn main() { + println!("cargo::rerun-if-changed=src/npi_c.c"); println!("Compiling using profile {:?}. Please condiser using test profile to fake LibNPI.so", env::var("PROFILE")); @@ -31,20 +35,27 @@ fn main() { } verdi_lib.push_str("/share/NPI/lib/linux64"); + + let mut npi_l1 = verdi_inc.clone(); + npi_l1.push_str("/share/NPI/L1/C/inc/"); + verdi_inc.push_str("/share/NPI/inc"); let npi_library_path = Path::new(&verdi_lib); let npi_include_path = Path::new(&verdi_inc); + let npi_l1_include_path = Path::new(&npi_l1); cc::Build::new() .cpp(true) // Switch to C++ library compilation. .file("./src/npi_c.c") - .flag("-lNPI -ldl -lpthread -lrt -lz") + .flag("-lNPI -ldl -lpthread -lrt -lz -lfsdb -lnpiL1") .include(npi_include_path) .include(npi_library_path) + .include(npi_l1_include_path) .compile("npi_c"); println!("cargo:rustc-link-lib=NPI"); - + println!("cargo:rustc-link-lib=fsdb"); + println!("cargo:rustc-link-lib=npiL1"); let key = "VERDI_HOME"; let verdi_home = match env::var(key) { diff --git a/libpresifuzz_observers/src/lib.rs b/libpresifuzz_observers/src/lib.rs index 576935a..7c5ba0a 100644 --- a/libpresifuzz_observers/src/lib.rs +++ b/libpresifuzz_observers/src/lib.rs @@ -5,3 +5,4 @@ pub mod verdi_observer; pub mod verdi_xml_observer; pub mod trace_observer; +pub mod fsdb_observer; diff --git a/libpresifuzz_observers/src/npi_c.c b/libpresifuzz_observers/src/npi_c.c index 982fd19..8f4642e 100644 --- a/libpresifuzz_observers/src/npi_c.c +++ b/libpresifuzz_observers/src/npi_c.c @@ -16,6 +16,8 @@ #ifndef DUMMY_LIB #include "npi.h" #include "npi_cov.h" +#include "npi_L1.h" +#include "npi_fsdb.h" #else typedef void* npiCovHandle; #endif @@ -30,6 +32,10 @@ typedef void* npiCovHandle; #include #include +#include +#include // for std::pair +#include // for rand(), srand() + #include "stdint.h" #ifdef __cplusplus @@ -57,7 +63,166 @@ extern "C" { void compute_score( npiCovHandle inst, npiCovHandle test, CoverageMap* cov_map); void update_cov_map(npiCovHandle db, uint32_t* map, unsigned map_size, unsigned coverage_type, char* filter); void vdb_init(); + + std::vector>* fsdb_sig_value_between(npiFsdbFileHandle file_hdl, const char* sig_name, npiFsdbTime begin_time, npiFsdbTime end_time, npiFsdbValType val_type); + + npiFsdbFileHandle fsdb_open(const char* fsdb_filename); + + void fsdb_close(npiFsdbFileHandle file_hdl); + + void fsdb_end(); + + void fsdb_init(); + + int fsdb_lib_sig_value_between( npiFsdbFileHandle file, + const char* sigName, + const npiFsdbTime &beginTime, + const npiFsdbTime &endTime, + fsdbTimeValPairVec_t &vc /*O*/, + const npiFsdbValType &format ); + + npiFsdbFileHandle fsdb_open(const NPI_BYTE8* fsdb_filename) { + return npi_fsdb_open(fsdb_filename); + } + void fsdb_close(npiFsdbFileHandle file_hdl) { + npi_fsdb_close(file_hdl); + } + +int fsdb_lib_val_to_str( const npiFsdbValue &value, string &str /*O*/ ) { + char buf[32];// 32: the digit of 64 bits integer is less or equal to 20 + + switch( value.format ) { + case npiFsdbBinStrVal: + case npiFsdbOctStrVal: + case npiFsdbDecStrVal: + case npiFsdbHexStrVal: + if ( !value.value.str ) + return 0; + str = value.value.str; + return 1; + case npiFsdbSintVal: + if ( sprintf( buf, "%-d", value.value.sint ) < 0 ) + return 0; + str = buf; + return 1; + case npiFsdbUintVal: + if ( sprintf( buf, "%-u", value.value.uint ) < 0 ) + return 0; + str = buf; + return 1; + case npiFsdbRealVal: + if ( sprintf( buf, "%-E", value.value.real ) < 0 ) + return 0; + str = buf; + return 1; + case npiFsdbStringVal: + case npiFsdbEnumStrVal: + if ( !value.value.str ) + return 0; + str = value.value.str; + return 1; + case npiFsdbSint64Val: + if ( sprintf( buf, "%lld", value.value.sint64 ) < 0 ) + return 0; + str = buf; + return 1; + case npiFsdbUint64Val: + if ( sprintf( buf, "%llu", value.value.uint64 ) < 0 ) + return 0; + str = buf; + return 1; + + default: + return 0; + } +} + + +int fsdb_lib_vct_time_val( npiFsdbVctHandle vct, + const npiFsdbValType &format, + npiFsdbTime &vctTime/*O*/, + string &val /*O*/) { + if ( npi_fsdb_vct_time( vct, &vctTime ) == 0 ) + return 0; + + npiFsdbValue vctVal; + vctVal.format = format; + if ( npi_fsdb_vct_value( vct, &vctVal ) == 0 ) + return 0; + + fsdb_lib_val_to_str( vctVal, val ); + return 1; +} + + + + std::vector>* fsdb_sig_value_between(npiFsdbFileHandle file_hdl, const char* sig_name, npiFsdbTime begin_time, npiFsdbTime end_time, npiFsdbValType format) { + + fsdbTimeValPairVec_t vc; + + if ( !file_hdl || !sig_name ) + return NULL; + + npiFsdbSigHandle sig = npi_fsdb_sig_by_name( file_hdl, sig_name, NULL ); + if ( !sig ) + return NULL; + else { + + npiFsdbVctHandle vct = npi_fsdb_create_vct( sig ); + if ( !vct ) + return NULL; + + npiFsdbFileHandle file = npi_fsdb_sig_file( sig ); + npi_fsdb_add_to_sig_list( file_hdl, sig ); + npi_fsdb_load_vc_by_range( file_hdl, begin_time, end_time ); + + npiFsdbTime vctTime; + string val; + if ( npi_fsdb_goto_time( vct, begin_time ) == 0 ) { // goto first VC + npi_fsdb_release_vct( vct ); + return 0; + } + + if ( fsdb_lib_vct_time_val( vct, format, vctTime, val ) == 0 ) { + npi_fsdb_release_vct( vct ); + return 0; + } + vc.push_back( make_pair ( begin_time, val ) ); // first VC in this range + + while( npi_fsdb_goto_next( vct ) ) { + if ( fsdb_lib_vct_time_val( vct, format, vctTime, val ) == 0 ) { + npi_fsdb_release_vct( vct ); + return 0; + } + if ( vctTime > end_time ) + break; + vc.push_back( make_pair( vctTime, val ) ); + } + + npi_fsdb_release_vct( vct ); + } + + // Now create a new vector to store pairs as (c_ulonglong, const char*) + auto vec = new std::vector>(); + + // Populate the new vector with data from fsdb_pairs + for (const auto& pair : vc) { + vec->emplace_back(pair.first, pair.second.c_str()); + } + + return vec; + } + + void fsdb_end() { + npi_end(); + } + + void fsdb_init(){ + vdb_init(); + } + + void vdb_init() { #ifdef DUMMY_LIB return; @@ -324,27 +489,97 @@ size_t compute_map_size(npiCovHandle db, unsigned coverage_type, char* filter) { } #ifdef C_APP -int main(int argc, char** argv) { +#include "npi.h" +#include "npi_L1.h" +#include "npi_fsdb.h" + +void traverse_hierarchy(npiFsdbHierHandle hier); +void traverse_signals(npiFsdbHierHandle hier); + +void traverse_signals(npiFsdbHierHandle hier) { + npiFsdbSigHandle sig; + + for (sig = npi_fsdb_hier_handle_sig_iter(hier); sig; sig = npi_fsdb_sig_handle_next(sig)) { + const char* sig_name = npi_fsdb_sig_handle_full_name(sig); + npiFsdbSigType sig_type = npi_fsdb_sig_handle_type(sig); + printf("Signal: %s, Type: %d\n", sig_name, sig_type); + } +} + +void traverse_hierarchy(npiFsdbHierHandle hier) { + const char* hier_name = npi_fsdb_hier_handle_full_name(hier); + printf("Hierarchy: %s\n", hier_name); + + // Traverse signals within this hierarchy + traverse_signals(hier); - vdb_init(); + // Traverse sub-hierarchies + npiFsdbHierHandle child; + for (child = npi_fsdb_hier_handle_child_iter(hier); child; child = npi_fsdb_hier_handle_next(child)) { + traverse_hierarchy(child); + } +} - void* db = vdb_cov_init(argv[1]); - char* filter = ""; +int main(int argc, char* argv[]) { + if (argc != 2) { + printf("Usage: %s \n", argv[0]); + return 1; + } - unsigned metric = atoi(argv[2]); + const char* fsdb_file = argv[1]; - size_t size = compute_map_size(db, metric, filter); - printf("Map size is %d for metric %d", size, metric); + // Initialize the NPI and open the FSDB file + if (!npi_init(NULL)) { + printf("Failed to initialize NPI.\n"); + return 1; + } - //uint32_t map[size] = {0}; + if (!npi_fsdb_open(fsdb_file)) { + printf("Failed to open FSDB file: %s\n", fsdb_file); + npi_end(); + return 1; + } - //update_cov_map(db, (uint32_t*)&map, size, 5, filter); + // Get the top hierarchy handle + npiFsdbHierHandle top = npi_fsdb_hier_handle_by_name("/"); + if (!top) { + printf("Failed to get top hierarchy.\n"); + npi_fsdb_close(); + npi_end(); + return 1; + } + + // Traverse the hierarchy starting from the top + traverse_hierarchy(top); + + // Cleanup + npi_fsdb_close(); + npi_end(); - //printf("["); - //unsigned i; - //for(i=0; i::new(); + //let rand = StdRand::with_seed(current_time().as_nanos() as u64); + //let corpus = InMemoryCorpus::::new(); - let mut feedback = ConstFeedback::new(true); - let mut objective = ConstFeedback::new(false); + //let mut feedback = ConstFeedback::new(true); + //let mut objective = ConstFeedback::new(false); - let mut spike_trace_observer = ExecTrace::::new("spike_trace", "./"); + //let mut spike_trace_observer = ExecTrace::::new("spike_trace", "./"); - let mut state = StdState::new( - rand, - corpus, - InMemoryCorpus::::new(), - &mut feedback, - &mut objective, - ) - .unwrap(); - state.set_max_size(1024); + //let mut state = StdState::new( + // rand, + // corpus, + // InMemoryCorpus::::new(), + // &mut feedback, + // &mut objective, + //) + //.unwrap(); + //state.set_max_size(1024); - let _ = spike_trace_observer.post_exec(&mut state, &input, &ExitKind::Ok); - println!("{:?}", spike_trace_observer.trace.len()) + //let _ = spike_trace_observer.post_exec(&mut state, &input, &ExitKind::Ok); + //println!("{:?}", spike_trace_observer.trace.len()) } }