/*
* 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 (c) 1994, by Sun Microsytems, Inc.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Interfaces for searching for elf specific information
*/
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <link.h>
#include "tnfctl_int.h"
#include "dbg.h"
/*
* Declarations
*/
static tnfctl_errcode_t dyn_findtag(
int limit, /* number of entries in table */
/* ---------------------------------------------------------------- */
/* ----------------------- Public Functions ----------------------- */
/* ---------------------------------------------------------------- */
/*
* _tnfctl_elf_dbgent() - this function finds the address of the
* debug struct (DT_DEBUG) in the target process. _DYNAMIC is a symbol
* present in every object. The one in the main executable references
* an array that is tagged with the kind of each member. We search
* for the tag of DT_DEBUG which is where the run time linker maintains
* a structure that references the shared object linked list.
*
* A side effect of searching for DT_DEBUG ensures that the executable is
* a dynamic executable - tracing only works on dynamic executables because
* static executables don't have relocation tables.
*/
{
int miscstat;
int objfd;
int num_dynentries = 0;
long dynam_tab_size;
if (prbstat)
return (_tnfctl_map_to_errcode(prbstat));
/* find the address of the symbol _DYNAMIC */
&dynamic_addr);
if (prexstat) {
goto Cleanup;
}
/* find the number of entries in the .dynamic section */
if (prexstat)
goto Cleanup;
/* read in the dynamic table from the image of the process */
if (!dynam_tab) {
return (TNFCTL_ERR_ALLOCFAIL);
}
if (miscstat) {
goto Cleanup;
}
if (prexstat) {
goto Cleanup;
}
*entaddr_p = dentry_addr;
if (dynam_tab)
return (prexstat);
}
/* ---------------------------------------------------------------- */
/* ----------------------- Private Functions ---------------------- */
/* ---------------------------------------------------------------- */
/*
* dyn_findtag() - searches tags in _DYNAMIC table
*/
static tnfctl_errcode_t
int limit, /* number of entries in table */
{ /* return value */
"sunw%verbosity 3; sunw%debug 'in loop'",
*dentry_address = dynam_addr +
return (TNFCTL_ERR_NONE);
}
if (--limit <= 0) {
"dyn_findtag: exceeded limit of table\n"));
return (TNFCTL_ERR_INTERNAL);
}
}
"dyn_findtag: couldn't find tag, last tag=%d\n",
return (TNFCTL_ERR_INTERNAL);
}
/*
* dynsec_num() - find the number of entries in the .dynamic section
*/
/*ARGSUSED*/
static tnfctl_errcode_t
{
int num_ent = 0;
"sunw%verbosity 2;"
"sunw%debug 'counting number of entries in .dynamic section'");
if (prexstat)
return (prexstat);
if (num_ent == 0)
return (TNFCTL_ERR_NOTDYNAMIC);
return (TNFCTL_ERR_NONE);
}
/*
* elf_dynmatch() - this function searches for the .dynamic section and
* returns the number of entries in it.
*/
/*ARGSUSED*/
static tnfctl_errcode_t
char *strs,
{
char *scn_name;
/* bail if this isn't a .dynamic section */
return (TNFCTL_ERR_NONE);
*ret = 0;
} else {
}
return (TNFCTL_ERR_NONE);
}