Add version check for VPI routines callback.

This commit is contained in:
Martin Whitaker 2019-10-30 20:03:33 +00:00
parent 9fb952ed72
commit d1d409fd88
4 changed files with 23 additions and 6 deletions

View File

@ -285,9 +285,13 @@ void vpip_set_return_value(int value)
vpip_routines->set_return_value(value);
}
DLLEXPORT void vpip_set_callback(vpip_routines_s*routines)
DLLEXPORT PLI_UINT32 vpip_set_callback(vpip_routines_s*routines, PLI_UINT32 version)
{
if (version != vpip_routines_version)
return 0;
vpip_routines = routines;
return 1;
}
#else

View File

@ -227,7 +227,7 @@ vpip_routines_s vpi_routines = {
.set_return_value = vpip_set_return_value,
};
typedef void (*vpip_set_callback_t)(vpip_routines_s*);
typedef PLI_UINT32 (*vpip_set_callback_t)(vpip_routines_s*, PLI_UINT32);
#endif
typedef void (*vlog_startup_routines_t)(void);
@ -248,7 +248,12 @@ bool load_vpi_module(const char*path)
return true;
}
vpip_set_callback_t set_callback = (vpip_set_callback_t)function;
set_callback(&vpi_routines);
if (!set_callback(&vpi_routines, vpip_routines_version)) {
cerr << "error: Failed to link '" << path << "'. "
"Try rebuilding it with iverilog-vpi." << endl;
ivl_dlclose(dll);
return true;
}
#endif
void*table = ivl_dlsym(dll, LU "vlog_startup_routines" TU);

View File

@ -683,6 +683,10 @@ extern void vpip_count_drivers(vpiHandle ref, unsigned idx,
* to be used by both the compiler and the simulator, we construct a jump table
* for the VPI routines that we can pass down to the VPI modules.
*/
// Increment the version number any time vpip_routines_s is changed.
static const PLI_UINT32 vpip_routines_version = 1;
typedef struct {
vpiHandle (*register_cb)(p_cb_data);
PLI_INT32 (*remove_cb)(vpiHandle);
@ -724,7 +728,7 @@ typedef struct {
void (*set_return_value)(int);
} vpip_routines_s;
extern DLLEXPORT void vpip_set_callback(vpip_routines_s*routines);
extern DLLEXPORT PLI_UINT32 vpip_set_callback(vpip_routines_s*routines, PLI_UINT32 version);
#endif // defined(__MINGW32__) || defined (__CYGWIN32__)

View File

@ -31,7 +31,7 @@ static ivl_dll_t*dll_list = 0;
static unsigned dll_list_cnt = 0;
#if defined(__MINGW32__) || defined (__CYGWIN32__)
typedef void (*vpip_set_callback_t)(vpip_routines_s*);
typedef PLI_UINT32 (*vpip_set_callback_t)(vpip_routines_s*, PLI_UINT32);
#endif
typedef void (*vlog_startup_routines_t)(void);
@ -226,7 +226,11 @@ void vpip_load_module(const char*name)
return;
}
vpip_set_callback_t set_callback = (vpip_set_callback_t)function;
set_callback(&vpi_routines);
if (!set_callback(&vpi_routines, vpip_routines_version)) {
fprintf(stderr, "Failed to link VPI module %s. Try rebuilding it with iverilog-vpi.\n", name);
ivl_dlclose(dll);
return;
}
#endif
void*table = ivl_dlsym(dll, LU "vlog_startup_routines" TU);