mdb_module.c revision 7c478bd95313f5f23a4c958a745db2134aa03244
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (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 2004 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <unistd.h>
#include <strings.h>
#include <dlfcn.h>
#include <link.h>
#include <mdb/mdb_module.h>
#include <mdb/mdb_modapi.h>
#include <mdb/mdb_debug.h>
#include <mdb/mdb_callb.h>
#include <mdb/mdb_string.h>
#include <mdb/mdb_frame.h>
/*
* For builtin modules, we set mod_init to this function, which just
* returns a constant modinfo struct with no dcmds and walkers.
*/
static const mdb_modinfo_t *
builtin_init(void)
{
return (&info);
}
int
{
*errmsgp = "no module name was specified\n";
return (0);
}
*errmsgp = "module name '%s' exceeds name length limit\n";
return (0);
}
*errmsgp = "module name '%s' contains illegal characters\n";
return (0);
}
*errmsgp = "%s module is already loaded\n";
return (0);
}
return (1);
}
int
mdb_module_t **mpp)
{
static const mdb_walker_t empty_walk_list[] = { 0 };
static const mdb_dcmd_t empty_dcmd_list[] = { 0 };
const mdb_modinfo_t *info;
const mdb_dcmd_t *dcp;
const mdb_walker_t *wp;
if (!(mode & MDB_MOD_BUILTIN)) {
goto err;
}
} else {
#ifdef _KMDB
/*
* mdb_ks is a special case - a builtin with _mdb_init and
* _mdb_fini routines. If we don't hack it in here, we'll have
* to duplicate most of the module creation code elsewhere.
*/
else
#endif
}
goto err;
}
goto err;
}
/*
* Reject modules compiled for a newer version of the debugger.
*/
warn("%s module requires newer mdb API version (%hu) than "
goto err;
}
/*
* Load modules compiled for the current API version.
*/
case MDB_API_VERSION:
case 2:
case 1:
/*
* Current API version -- copy entire modinfo
* structure into our own private storage.
*/
break;
default:
/*
* Too old to be compatible -- abort the load.
*/
warn("%s module is compiled for obsolete mdb API "
goto err;
}
/*
* Before we actually go ahead with the load, we need to check
* each dcmd and walk structure for any invalid values:
*/
warn("dcmd name '%s' contains illegal characters\n",
goto err;
}
warn("dcmd '%s' must have a description\n",
goto err;
}
warn("dcmd '%s' has a NULL function pointer\n",
goto err;
}
}
warn("walk name '%s' contains illegal characters\n",
goto err;
}
warn("walk '%s' must have a description\n",
goto err;
}
warn("walk '%s' has a NULL walk_step function\n",
goto err;
}
}
/*
* Now that we've established that there are no problems,
* we can go ahead and hash the module, and its dcmds and walks:
*/
}
}
/*
* Add the module to the end of the list of modules in load-dependency
* order. We maintain this list so we can unload in reverse order.
*/
} else {
}
return (0);
err:
return (-1);
}
mdb_module_load_builtin(const char *name)
{
return (NULL);
return (mp);
}
int
mdb_module_unload_common(const char *name)
{
if (v == NULL)
return (set_errno(EMDB_NOMOD));
mod = mdb_nv_get_cookie(v);
return (set_errno(EMDB_BUILTINMOD));
}
} else
} else
}
}
return (0);
}
int
{
if (flags & MDB_MOD_FORCE)
nflag |= MDB_NV_INTERPOS;
if (v != NULL)
return (set_errno(EMDB_DCMDEXISTS));
return (0);
}
int
{
if (v == NULL)
return (set_errno(EMDB_NODCMD));
idcp = mdb_nv_get_cookie(v);
/*
* If we're removing a dcmd that is part of the most recent command,
* we need to free mdb.m_lastcp so we don't attempt to execute some
* text we've removed from our address space if -o repeatlast is set.
*/
}
break;
}
}
return (0);
}
/*ARGSUSED*/
static int
{
return (WALK_NEXT);
}
/*ARGSUSED*/
static void
{
/* Nothing to do here */
}
int
{
if (flags & MDB_MOD_FORCE)
nflag |= MDB_NV_INTERPOS;
if (v != NULL)
return (set_errno(EMDB_WALKEXISTS));
return (0);
}
int
{
if (v == NULL)
return (set_errno(EMDB_NOWALK));
iwp = mdb_nv_get_cookie(v);
return (0);
}
void
{
/*
* We unload modules in the reverse order in which they were loaded
* so as to allow _mdb_fini routines to invoke code which may be
* present in a previously-loaded module (such as mdb_ks, etc.).
*/
}
}