rtld.c revision e0e638160d72f8685f1481f6308bc368cd233c3f
/*
* 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.
*/
#include <msg.h>
#include <_rtld.h>
#include <conv.h>
#include <sys/mdb_modapi.h>
#include <stdlib.h>
/*
* Data structure for walkers.
*/
typedef struct {
} W_desc;
/*
* Flags values for dcmds
*/
static const mdb_bitmask_t rtflags_bits[] = {
{ NULL, 0, 0}
};
static const mdb_bitmask_t rtflags1_bits[] = {
{ NULL, 0, 0}
};
static const mdb_bitmask_t rtaflags_bits[] = {
{ NULL, 0, 0}
};
static const mdb_bitmask_t rtmode_bits[] = {
{ NULL, 0, 0}
};
static const mdb_bitmask_t bndflags_bits[] = {
{ NULL, 0, 0}
};
static const mdb_bitmask_t grhflags_bits[] = {
{ NULL, 0, 0}
};
static const mdb_bitmask_t grdflags_bits[] = {
{ NULL, 0, 0}
};
static const mdb_bitmask_t lmc_bits[] = {
{ NULL, 0, 0}
};
/*
* Obtain a string - typically a link-map name.
*/
static char *
{
static char str[MAXPATHLEN];
if (addr) {
return (0);
}
return (str);
}
return ((char *)MSG_ORIG(MSG_STR_EMPTY));
}
/*
* Obtain a link-map name.
*/
static char *
{
if (addr) {
return (0);
}
MSG_ORIG(MSG_STR_NAME)));
}
return ((char *)MSG_ORIG(MSG_STR_EMPTY));
}
void
dcmd_Bind_help(void)
{
}
static int
/* ARGSUSED2 */
{
char *str;
/*
* Insure we have a valid address.
*/
if ((flags & DCMD_ADDRSPEC) == 0) {
return (DCMD_USAGE);
}
/*
* Obtain the binding descriptor.
*/
return (DCMD_ERR);
}
/*
* Establish the identity of the caller.
*/
return (DCMD_ERR);
/*
* Establish the identity of the dependency.
*/
return (DCMD_ERR);
/*
* Display any flags.
*/
return (DCMD_OK);
}
static void
dcmd_Depends_help(void)
{
}
static int
{
/*
* Obtain the APlist and determine its number of elements and those
* that are in use.
*/
addr);
return (DCMD_ERR);
}
return (DCMD_OK);
/*
* Under verbose mode print the name of each dependency. An APlist can
* have a variable number of data items, so read each individual entry.
*/
return (DCMD_ERR);
}
mdb_inc_indent(4);
mdb_dec_indent(4);
return (DCMD_ERR);
}
datap += sizeof (void *);
return (DCMD_ERR);
}
mdb_dec_indent(4);
return (DCMD_ERR);
}
}
mdb_dec_indent(4);
return (DCMD_OK);
}
static int
{
char *str;
/*
* Insure we have a valid address, and provide for a -v option.
*/
if ((flags & DCMD_ADDRSPEC) == 0) {
return (DCMD_USAGE);
}
return (DCMD_USAGE);
/*
* Read the Rt_map contents.
*/
return (DCMD_ERR);
}
MSG_ORIG(MSG_STR_NAME))) == 0)
return (DCMD_ERR);
return (DCMD_OK);
}
static void
dcmd_Callers_help(void)
{
}
static int
{
char *str;
/*
* Insure we have a valid address, and provide for a -v option.
*/
if ((flags & DCMD_ADDRSPEC) == 0) {
return (DCMD_USAGE);
}
return (DCMD_USAGE);
/*
* Read the Rt_map contents.
*/
return (DCMD_ERR);
}
MSG_ORIG(MSG_STR_NAME))) == 0)
return (DCMD_ERR);
return (DCMD_OK);
}
void
dcmd_rtmap_help(void)
{
}
static int
/* ARGSUSED2 */
{
char *str;
if ((flags & DCMD_ADDRSPEC) == 0) {
return (DCMD_USAGE);
}
return (DCMD_ERR);
}
/*
* Determine the objects name. NAME() is the name by which the object
* has been opened, typically from adding a search path to a file name.
* PATHNAME() is the fully resolve name, which is displayed by the proc
* tools and debuggers. If the two names differ, print the PATHNAME().
*/
MSG_ORIG(MSG_STR_NAME))) == 0)
return (DCMD_ERR);
MSG_ORIG(MSG_STR_PATHNAME))) == 0)
return (DCMD_ERR);
}
MSG_ORIG(MSG_STR_REFNAME))) == 0)
return (DCMD_ERR);
MSG_ORIG(MSG_STR_RPATH))) == 0)
return (DCMD_ERR);
}
return (DCMD_OK);
}
static int
{
char *str;
return (0);
}
MSG_ORIG(MSG_STR_NAME))) == 0)
return (DCMD_ERR);
return (0);
}
void
dcmd_Rtmaps_help(void)
{
}
static int
{
const char *str;
/*
* '-v' - Verbose output of rtmap
*/
return (DCMD_USAGE);
/*
* If an address was provided use it.
*/
if (flags & DCMD_ADDRSPEC) {
!(flg & RTLD_FLG_VERBOSE)) {
}
return (DCMD_ERR);
return (DCMD_OK);
}
/*
* Otherwise traverse the dynlm_list and display each link-map.
*/
return (DCMD_ERR);
}
return (DCMD_ERR);
}
return (DCMD_OK);
}
aplp);
}
return (DCMD_ERR);
}
return (DCMD_ERR);
}
mdb_inc_indent(2);
else
mdb_inc_indent(2);
!(flg & RTLD_FLG_VERBOSE)) {
}
mdb_dec_indent(4);
return (DCMD_ERR);
}
mdb_dec_indent(4);
flags &= ~DCMD_LOOPFIRST;
}
return (DCMD_OK);
}
void
dcmd_Setenv_help(void)
{
}
/*
* As of s10, mdb provides its own setenv command. This command allows the
* environment of the process being controlled to be changed at any time.
* Prior to this, ld.so.1 provided it's own, more primitive implementation.
* This allowed for changing mdb's environment only, which if it was changed
* before the application ws executed, would be copied to the applications
* environment. Thus, we could start mdb, set an LD_ variable within its
* environment (which it's own ld.so.1 had already finished processing), and
* have this setting be inherited by the application.
*/
static int
/* ARGSUSED */
{
char *str;
argv) == 0)
return (DCMD_OK);
return (DCMD_USAGE);
return (DCMD_ERR);
return (DCMD_OK);
}
/*
* Walk Rt_map lists
*/
static int
{
return (WALK_ERR);
}
return (WALK_NEXT);
}
static int
{
int status;
return (WALK_DONE);
return (WALK_DONE);
}
return (status);
}
static const mdb_bitmask_t lml_flags_bit[] = {
{ NULL, 0, 0}
};
static const mdb_bitmask_t lml_tflags_bit[] = {
{ NULL, 0, 0}
};
void
dcmd_Lm_list_help(void)
{
}
static int
/* ARGSUSED1 */
{
const char *str;
return (DCMD_USAGE);
addr);
return (DCMD_ERR);
}
else
return (DCMD_ERR);
}
/*
* Determine whether the Alist has been populated. Note, the
* implementation first reserves an alist entry, and initializes
* this element when the first link-map is processed. Thus,
* there's a window when nitems is updated, but before the next
* element has been initialized.
*/
datap) == -1) {
return (DCMD_ERR);
}
}
mdb_inc_indent(2);
mdb_inc_indent(2);
lmc_bits);
rtmap_format, (void *)0,
mdb_dec_indent(4);
return (DCMD_ERR);
}
} else
datap) == -1) {
mdb_dec_indent(4);
return (DCMD_ERR);
}
rtmap_format, (void *)0,
mdb_dec_indent(4);
return (DCMD_ERR);
}
} else
0, MSG_ORIG(MSG_STR_EMPTY));
}
mdb_dec_indent(2);
}
mdb_dec_indent(2);
}
return (DCMD_OK);
}
static int
/* ARGSUSED2 */
{
/*
* If an address was provided us it.
*/
if (flags & DCMD_ADDRSPEC)
/*
* Otherwise traverse the dynlm_list and display each link-map list.
*/
return (DCMD_ERR);
}
return (DCMD_ERR);
}
return (DCMD_OK);
}
aplp);
return (DCMD_ERR);
}
return (DCMD_ERR);
}
mdb_inc_indent(2);
mdb_dec_indent(2);
return (DCMD_ERR);
}
mdb_dec_indent(2);
flags &= ~DCMD_LOOPFIRST;
}
return (DCMD_OK);
}
void
dcmd_GrpDesc_help(void)
{
}
static int
/* ARGSUSED2 */
{
char *str;
/*
* Insure we have a valid address.
*/
if ((flags & DCMD_ADDRSPEC) == 0) {
return (DCMD_USAGE);
}
addr);
return (DCMD_ERR);
}
return (DCMD_ERR);
return (DCMD_OK);
}
void
dcmd_GrpHdl_help(void)
{
}
static int
/* ARGSUSED2 */
{
char *str;
/*
* Insure we have a valid address, and provide for a -v option.
*/
if ((flags & DCMD_ADDRSPEC) == 0) {
return (DCMD_USAGE);
}
return (DCMD_USAGE);
addr);
return (DCMD_ERR);
}
/*
* Determine the handles owner. Note that an orphaned handle may no
* longer contain its originating owner.
*/
return (DCMD_ERR);
} else
if (gh.gh_depends == 0) {
return (DCMD_OK);
}
return (DCMD_ERR);
}
return (DCMD_OK);
mdb_inc_indent(4);
/*
* Under verbose mode print the name of each dependency. An Alist can
* have a variable number of data items, so read each individual entry.
*/
mdb_dec_indent(4);
return (DCMD_ERR);
}
mdb_dec_indent(4);
return (DCMD_ERR);
}
}
mdb_dec_indent(4);
return (DCMD_OK);
}
static void
dcmd_Handles_help(void)
{
}
static int
{
char *str;
/*
* Insure we have a valid address, and provide for a -v option.
*/
if ((flags & DCMD_ADDRSPEC) == 0) {
return (DCMD_USAGE);
}
return (DCMD_USAGE);
/*
* Read the Rt_map contents.
*/
return (DCMD_ERR);
}
MSG_ORIG(MSG_STR_NAME))) == 0)
return (DCMD_ERR);
return (DCMD_OK);
addr);
return (DCMD_ERR);
}
return (DCMD_OK);
/*
* Under verbose mode print the name of each dependency. An APlist can
* have a variable number of data items, so read each individual entry.
*/
return (DCMD_ERR);
}
mdb_inc_indent(4);
mdb_dec_indent(4);
return (DCMD_ERR);
}
nitems = 1;
datap += sizeof (void *);
return (DCMD_ERR);
}
mdb_dec_indent(4);
return (DCMD_ERR);
}
}
mdb_dec_indent(4);
return (DCMD_OK);
}
static void
dcmd_Groups_help(void)
{
}
static int
{
char *str;
/*
* Insure we have a valid address, and provide for a -v option.
*/
if ((flags & DCMD_ADDRSPEC) == 0) {
return (DCMD_USAGE);
}
return (DCMD_USAGE);
/*
* Read the Rt_map contents.
*/
return (DCMD_ERR);
}
MSG_ORIG(MSG_STR_NAME))) == 0)
return (DCMD_ERR);
return (DCMD_OK);
addr);
return (DCMD_ERR);
}
return (DCMD_OK);
/*
* Under verbose mode print the name of each dependency. An APlist can
* have a variable number of data items, so read each individual entry.
*/
return (DCMD_ERR);
}
mdb_inc_indent(4);
mdb_dec_indent(4);
return (DCMD_ERR);
}
datap += sizeof (void *);
return (DCMD_ERR);
}
mdb_dec_indent(4);
return (DCMD_ERR);
}
}
mdb_dec_indent(4);
return (DCMD_OK);
}
static void
dcmd_ElfDyn_help(void)
{
}
static int
/* ARGSUSED2 */
{
const char *dynstr;
if ((flags & DCMD_ADDRSPEC) == 0)
return (DCMD_USAGE);
addr);
return (DCMD_ERR);
}
return (DCMD_OK);
}
static void
dcmd_ElfEhdr_help(void)
{
}
static int
/* ARGSUSED2 */
{
const char *flgs;
if ((flags & DCMD_ADDRSPEC) == 0)
return (DCMD_USAGE);
addr);
return (DCMD_ERR);
}
/*
* Line up the flags differently depending on whether we
* received a numeric (e.g. "0x200") or text representation
* (e.g. "[ EF_SPARC_SUN_US1 ]").
*/
0, &ehdr_flags_buf);
if (flgs[0] == '[')
else
return (DCMD_OK);
}
static void
dcmd_ElfPhdr_help(void)
{
}
static int
/* ARGSUSED2 */
{
if ((flags & DCMD_ADDRSPEC) == 0)
return (DCMD_USAGE);
addr);
return (DCMD_ERR);
}
&phdr_flags_buf));
return (DCMD_OK);
}
static const mdb_dcmd_t dcmds[] = {
{ NULL }
};
static const mdb_walker_t walkers[] = {
{ NULL }
};
static const mdb_modinfo_t modinfo = {
};
const mdb_modinfo_t *
_mdb_init(void)
{
return (&modinfo);
}