/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* Driver-side functions for loading and unloading dmods.
*/
#include <sys/kobj_impl.h>
#include <kmdb/kmdb_wr_impl.h>
#include <kmdb/kmdb_kdi.h>
#include <mdb/mdb_errno.h>
/*
* When a load is attempted, a check is first made of the modules on the
* kctl_dmods list. If a module is found, the load will not proceed.
* kctl_dmods_lock must be held while traversing kctl_dmods, and while adding
* to and subtracting from it.
*/
/*
* Used to track outstanding driver-initiated load notifications. These
* notifications have been allocated by driver, and thus must be freed by the
* driver in the event of an emergency unload. If we don't free them free
* them ourselves, they'll leak. Granted, the world is probably melting down
* at that point, but there's no reason why we shouldn't tidy up the deck
* chairs before we go.
*/
static int
{
int i;
/* If they gave us an absolute path, we don't need to search */
if (modname[0] == '/') {
modname);
return (0);
}
return (0);
kobj_close(fd);
return (1);
}
kctl_dprintf("Can't load dmod from %s/%s - "
continue;
}
continue;
kobj_close(fd);
/* Found it */
return (1);
}
/* No luck */
return (0);
}
static void
{
return;
}
int
{
int rc;
/* Have we already loaded this dmod? */
return (-1);
}
}
/*
* If we find something that looks like a dmod, create a modctl for it,
* and add said modctl to our dmods list. This will allow us to drop
* the dmods lock, while still preventing duplicate loads. If we aren't
* able to actually load the dmod, we can always remove the modctl
* later.
*/
return (-1);
}
else
if (rc != 0) {
return (-1);
}
/*
* It worked! If the module has any CTF data, decompress it, and make a
* note of the load.
*/
kctl_warn("failed to decompress CTF data for dmod %s: %s",
}
return (0);
}
/*
* Driver-initiated loads. Load the module and announce it to the debugger.
*/
void
{
/*
* If we're loading at boot, the kmdb_wr_load_t will have been
* "allocated" by krtld, and will thus not be under the control of
* kmem. We need to ensure that we don't attempt to free it when
* we get it back from the debugger.
*/
if (kctl_dmod_load(dlr) < 0) {
return;
}
/*
* Add to the list of open driver-initiated loads. We need to track
* these so we can free them (and thus avoid leaks) in the event that
* the debugger needs to be blown away before it can return them.
*/
if (kctl_dmod_loads != NULL)
}
void
kctl_dmod_load_all(void)
{
/*
* The standard list of modules isn't populated until the tail end of
* kobj_init(). Prior to that point, the only available list is that of
* primaries. We'll use that if the normal list isn't ready yet.
*/
/* modules hasn't been initialized yet -- use primaries */
} else {
do {
}
}
void
{
/* Remove from the list of open driver-initiated requests */
else
}
static int
{
struct modctl *m;
if (m == modp)
break;
}
if (m != modp)
return (ENOENT);
/* Found it */
modp->mod_loaded = 0;
/* Remove it from our dmods list */
return (0);
}
void
{
int rc;
}
}
/*
* This will be called during shutdown. The debugger has been stopped, we're
* off the module notification list, and we've already processed everything in
* the driver's work queue. We should have received (and processed) unload
* requests for each of the dmods we've loaded. To be safe, however, we'll
* double-check.
*
* If we're doing an emergency shutdown, there may be outstanding
* driver-initiated messages that haven't been returned to us. The debugger is
* dead, so it's not going to be returning them. We'll leak them unless we
* find and free them ourselves.
*/
void
kctl_dmod_unload_all(void)
{
(void) kctl_dmod_unload_common(modp);
kctl_dprintf("freed orphan load notification for %s",
}
}
{
int i;
} else {
kctl_dprintf("changing dmod path to NULL");
}
}
return (opth);
}
void
kctl_dmod_path_reset(void)
{
}
}
void
kctl_dmod_sync(void)
{
/*
* kobj_sync() has no visibility into our dmods, so we need to
* explicitly tell krtld to export the portions of our dmods that were
* allocated using boot scratch memory.
*/
}
void
kctl_dmod_init(void)
{
kdi_dmods = &kctl_dmods;
}
void
kctl_dmod_fini(void)
{
}