/*
* 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 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <sys/elf_SPARC.h>
#include <libproc.h>
#include <libctf.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <mdb/mdb_string.h>
#include <mdb/mdb_argvec.h>
#include <mdb/mdb_target.h>
#include <mdb/mdb_debug.h>
#include <mdb/mdb_conf.h>
#include <mdb/mdb_module.h>
#include <mdb/mdb_modapi.h>
#include <mdb/mdb_stdlib.h>
#include <mdb/mdb_io_impl.h>
#include <mdb/mdb_help.h>
#include <mdb/mdb_disasm.h>
#include <mdb/mdb_frame.h>
#include <mdb/mdb_evset.h>
#include <mdb/mdb_print.h>
#include <mdb/mdb_demangle.h>
enum {
};
enum {
};
typedef struct {
const char *nm_name;
const char *nm_object;
} nm_sym_t;
typedef struct {
const char *nii_pfmt;
const char *nii_ofmt;
typedef struct {
void *ngs_arg;
const char *ngs_object;
typedef struct {
static const char *
{
switch (GELF_ST_TYPE(info)) {
case STT_NOTYPE:
return ("NOTY");
case STT_OBJECT:
return ("OBJT");
case STT_FUNC:
return ("FUNC");
case STT_SECTION:
return ("SECT");
case STT_FILE:
return ("FILE");
case STT_COMMON:
return ("COMM");
case STT_TLS:
return ("TLS");
case STT_SPARC_REGISTER:
return ("REGI");
default:
return ("?");
}
}
static const char *
{
switch (GELF_ST_BIND(info)) {
case STB_LOCAL:
return ("LOCL");
case STB_GLOBAL:
return ("GLOB");
case STB_WEAK:
return ("WEAK");
default:
return ("?");
}
}
static const char *
{
switch (shndx) {
case SHN_UNDEF:
return ("UNDEF");
case SHN_ABS:
return ("ABS");
case SHN_COMMON:
return ("COMMON");
default:
return (buf);
}
}
static char *
{
int n;
int i;
return (NULL);
else
if (len <= n)
return (start);
buf += n;
len -= n;
for (i = 0; i < f.ctc_argc; i++) {
else
if (len <= n)
return (start);
buf += n;
len -= n;
sep = ", ";
}
if (f.ctc_flags & CTF_FUNC_VARARG) {
if (len <= n)
return (start);
buf += n;
len -= n;
} else if (f.ctc_argc == 0) {
if (len <= n)
return (start);
buf += n;
len -= n;
}
return (start);
}
static void
{
}
str = "<unknown type>";
}
static void
{
} else {
}
}
static void
{
if (obj == MDB_TGT_OBJ_EXEC)
obj = "exec";
else if (obj == MDB_TGT_OBJ_RTLD)
obj = "rtld";
else if (obj == MDB_TGT_OBJ_EVERY)
obj = "";
}
/*ARGSUSED*/
static int
{
return (0);
mdb_printf("\n");
return (0);
}
/*ARGSUSED*/
static int
{
}
/*ARGSUSED*/
static int
{
return (0);
}
/*ARGSUSED*/
static int
{
const char *opts;
case STT_FUNC:
opts = "-f";
break;
case STT_OBJECT:
opts = "-o";
break;
default:
opts = "";
}
mdb_printf("%#llr::nmadd %s -s %#llr %s\n",
return (0);
}
/*ARGSUSED*/
static int
{
(*cntp)++;
return (0);
}
/*ARGSUSED*/
static int
{
return (0);
}
/*ARGSUSED*/
static int
{
(*sympp)++;
return (0);
}
/*ARGSUSED*/
static int
{
return (0);
}
static int
{
}
static int
{
}
static int
{
ngsp->ngs_object));
}
static void
{
}
nm_iter_info_t *);
/*ARGSUSED*/
static int
{
/*
* Since we're interating over all the objects in a target,
* don't return an error if we hit an object that we can't
* get symbol data for.
*/
return (0);
}
int
{
if (object == MDB_TGT_OBJ_EVERY) {
}
}
/*ARGSUSED*/
int
{
enum {
};
{ NM_FMT_INDEX, "ndx" },
{ NM_FMT_VALUE, "val" },
{ NM_FMT_SIZE, "sz" },
{ NM_FMT_TYPE, "type" },
{ NM_FMT_BIND, "bind" },
{ NM_FMT_OTHER, "oth" },
{ NM_FMT_SHNDX, "shndx" },
{ NM_FMT_NAME, "name" },
{ NM_FMT_CTYPE, "ctype" },
{ NM_FMT_OBJECT, "obj" },
{ NM_FMT_CTFID, "ctfid" },
{ 0, NULL }
};
{ NM_TYPE_NOTY, "noty" },
{ NM_TYPE_OBJT, "objt" },
{ NM_TYPE_FUNC, "func" },
{ NM_TYPE_SECT, "sect" },
{ NM_TYPE_FILE, "file" },
{ NM_TYPE_COMM, "comm" },
{ NM_TYPE_TLS, "tls" },
{ NM_TYPE_REGI, "regi" },
{ 0, NULL }
};
int i;
int hwidth;
/* default output columns */
/* default output types */
NULL);
if (i != argc) {
if (flags & DCMD_ADDRSPEC)
return (DCMD_USAGE);
return (DCMD_USAGE);
else
} else
return (DCMD_USAGE);
}
case 8:
break;
case 10:
break;
default:
}
}
case NM_DEC:
#ifdef _LP64
hwidth = 20;
#else
hwidth = 10;
#endif
break;
case NM_HEX:
#ifdef _LP64
hwidth = 18;
#else
hwidth = 10;
#endif
break;
case NM_OCT:
#ifdef _LP64
hwidth = 22;
#else
hwidth = 11;
#endif
break;
default:
mdb_warn("-d/-o/-x options are mutually exclusive\n");
return (DCMD_USAGE);
}
return (DCMD_USAGE);
}
return (DCMD_USAGE);
}
mdb_printf("%<u>");
mdb_printf("%</u>\n");
}
else
else
if (flags & DCMD_ADDRSPEC)
else
if (flags & DCMD_ADDRSPEC) {
/* gather relevant data for the specified addr */
&si) == -1) {
return (DCMD_ERR);
}
!= NULL) {
/*
* Try to find a better match for the syminfo.
*/
}
} else {
}
if (nsyms == 0)
return (DCMD_OK);
else
if (flags & DCMD_ADDRSPEC) {
&nii) == -1) {
mdb_warn("failed to iterate over symbols");
return (DCMD_ERR);
}
if (optf & NM_SORT_NAME)
else
}
else
}
} else {
== -1) {
mdb_warn("failed to iterate over symbols");
return (DCMD_ERR);
}
}
return (DCMD_OK);
}
int
{
int i;
if (!(flags & DCMD_ADDRSPEC))
return (DCMD_USAGE);
return (DCMD_USAGE);
mdb_warn("end (%p) is less than start address (%p)\n",
return (DCMD_USAGE);
}
}
if (opt_f)
if (opt_o)
if (opt_e)
if (opt_s)
return (DCMD_OK);
}
/*ARGSUSED*/
int
{
const char *name;
return (DCMD_USAGE);
mdb_printf("deleted %s, value=%llr size=%llr\n",
return (DCMD_OK);
}
return (DCMD_ERR);
}
void
nm_help(void)
{
mdb_printf("-D print .dynsym instead of .symtab\n"
"-P print private symbol table instead of .symtab\n"
"-d print value and size in decimal\n"
"-g only print global symbols\n"
"-h suppress header line\n"
"-n sort symbols by name\n"
"-o print value and size in octal\n"
"-p print symbols as a series of ::nmadd commands\n"
"-u only print undefined symbols\n"
"-v sort symbols by value\n"
"-x print value and size in hexadecimal\n"
"-f format use specified format\n"
" ndx, val, sz, type, bind, oth, shndx, "
"name, ctype, obj\n"
"-t types display symbols with the specified types\n"
" noty, objt, func, sect, file, regi\n"
"obj specify object whose symbol table should be used\n");
}
void
nmadd_help(void)
{
mdb_printf("-f set type of symbol to STT_FUNC\n"
"-o set type of symbol to STT_OBJECT\n"
"-e end set size of symbol to end - start address\n"
"-s size set size of symbol to explicit value\n"
"name specify symbol name to add\n");
}