linker: Avoid invoking eventhandlers on incompletely loaded files
We do not invoke the kld_load eventhandler until after the file is fully linked, so don't invoke the kld_unload_try or kld_unload event handlers unless the file is fully linked either. In my case, the dtrace SDT kld_unload_try handler was running before relocations were processed against the file, and that caused problems when sdt_kld_unload_probes() accesses elements of a linker set. Move the kld_unload handler invocation earlier, to after sysuninits have been run. This is a bit more consistent with the kld_load handler. PR: 291238 Reviewed by: imp, emaste, kib MFC after: 2 weeks Differential Revision: https://reviews.freebsd.org/D53938
This commit is contained in:
@@ -703,9 +703,11 @@ linker_file_unload(linker_file_t file, int flags)
|
||||
|
||||
/* Give eventhandlers a chance to prevent the unload. */
|
||||
error = 0;
|
||||
EVENTHANDLER_INVOKE(kld_unload_try, file, &error);
|
||||
if (error != 0)
|
||||
return (EBUSY);
|
||||
if ((file->flags & LINKER_FILE_LINKED) != 0) {
|
||||
EVENTHANDLER_INVOKE(kld_unload_try, file, &error);
|
||||
if (error != 0)
|
||||
return (EBUSY);
|
||||
}
|
||||
|
||||
KLD_DPF(FILE, ("linker_file_unload: file is unloading,"
|
||||
" informing modules\n"));
|
||||
@@ -768,10 +770,12 @@ linker_file_unload(linker_file_t file, int flags)
|
||||
* Don't try to run SYSUNINITs if we are unloaded due to a
|
||||
* link error.
|
||||
*/
|
||||
if (file->flags & LINKER_FILE_LINKED) {
|
||||
if ((file->flags & LINKER_FILE_LINKED) != 0) {
|
||||
file->flags &= ~LINKER_FILE_LINKED;
|
||||
linker_file_unregister_sysctls(file);
|
||||
linker_file_sysuninit(file);
|
||||
EVENTHANDLER_INVOKE(kld_unload, file->filename, file->address,
|
||||
file->size);
|
||||
}
|
||||
TAILQ_REMOVE(&linker_files, file, link);
|
||||
|
||||
@@ -788,9 +792,6 @@ linker_file_unload(linker_file_t file, int flags)
|
||||
|
||||
LINKER_UNLOAD(file);
|
||||
|
||||
EVENTHANDLER_INVOKE(kld_unload, file->filename, file->address,
|
||||
file->size);
|
||||
|
||||
if (file->filename) {
|
||||
free(file->filename, M_LINKER);
|
||||
file->filename = NULL;
|
||||
|
||||
Reference in New Issue
Block a user