xref: /onnv-gate/usr/src/cmd/sgs/prof/common/symintLoad.c (revision 6951:59445bec7ef4)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
53621Sab196087  * Common Development and Distribution License (the "License").
63621Sab196087  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
21211Smike_s 
22211Smike_s /*
23*6951Sab196087  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
24211Smike_s  * Use is subject to license terms.
25211Smike_s  */
26211Smike_s 
270Sstevel@tonic-gate /*	Copyright (c) 1988 AT&T	*/
280Sstevel@tonic-gate /*	  All Rights Reserved  	*/
290Sstevel@tonic-gate 
300Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
310Sstevel@tonic-gate 
320Sstevel@tonic-gate /*
33211Smike_s  *	File: symintLoad.c
34211Smike_s  *	Date: 12/15/88
35211Smike_s  *
36211Smike_s  *	This file provides code to build the profiling symbol array
37211Smike_s  *	(array of PROF_SYMBOL).  This array contains all of the
38211Smike_s  *	symbol table information plus selected debug information for
39211Smike_s  *	each file and each function that has a coverage array.
40211Smike_s  *
41211Smike_s  *	The symbol table contains entries for every file, every
42211Smike_s  *	function, and every coverage array.  The debug information
43211Smike_s  *	has corresponding entries except that there are no entries
44211Smike_s  *	for the coverage arrays.  (This may change later.)
45211Smike_s  *
46211Smike_s  *	The algorithm for building the profiling symbol array
47211Smike_s  *	consists of scanning the symbol table for file, function,
48211Smike_s  *	and coverage array entries and building an entry for each.
49211Smike_s  *	The construction of an entry is constrained by the
50211Smike_s  *	following factors:
51211Smike_s  *
52211Smike_s  *		- An entry is built for every file.
53211Smike_s  *
54211Smike_s  *		- An entry is built for a function only if there
55211Smike_s  *		is a corresponding coverage array for the function.
56211Smike_s  *
57211Smike_s  *		- Entries must be ordered in the sense that each
58211Smike_s  *		non-file entry points to its owner file and each
59211Smike_s  *		file entry points to the next file (or null).
60211Smike_s  *
61211Smike_s  *		- The assembler specification (see C Issue 5 3B2
62211Smike_s  *		Assembler System Test Specification by Howe, p. 28)
63211Smike_s  *		states that all local symbols follow their file
64211Smike_s  *		symbol in the symbol table.  This allows us to relate
65211Smike_s  *		a function and its coverage array to the file that
66211Smike_s  *		contains it.
67211Smike_s  *
68211Smike_s  *		- For each symbol included in the profiling symbol
69211Smike_s  *		array, all corresponding symbol table information must
70211Smike_s  *		be present together with selected debug information.
71211Smike_s  *		Therefore, the correspondence between a symbol table
72211Smike_s  *		entry and a debug entry must be established.
73211Smike_s  *
74211Smike_s  *		- Although duplicate (static) function names may appear,
75211Smike_s  *		the names are unique within a given file.  Also, the
76211Smike_s  *		value (address) of each function is included in both
77211Smike_s  *		the symbol table information and the debug information.
78211Smike_s  *		This provides a verifable correspondence between these
79211Smike_s  *		information sets.
80211Smike_s  *
81211Smike_s  */
820Sstevel@tonic-gate 
830Sstevel@tonic-gate #include "string.h"
840Sstevel@tonic-gate #include "symint.h"
850Sstevel@tonic-gate #include "debug.h"
860Sstevel@tonic-gate 
870Sstevel@tonic-gate static PROF_FILE	*profPtr;
880Sstevel@tonic-gate 
89211Smike_s /* LINTED: set but not used */
90211Smike_s static int	prstsym_size;	/* size of a symbol table symbol */
91211Smike_s 
92211Smike_s static PROF_SYMBOL	*prsym_list_p = 0;	/* the list to return. */
930Sstevel@tonic-gate 
940Sstevel@tonic-gate /*
950Sstevel@tonic-gate  * _symintLoad(proffilePtr)
960Sstevel@tonic-gate  * proffilePtr	- PROF_FILE pointer returned by _symintOpen().
97211Smike_s  *
980Sstevel@tonic-gate  * returns PROF_SYMBOL * - pointer to the malloc-ed array of
99211Smike_s  *			   symbol information entries, or
100211Smike_s  *			   NULL if fails.
101211Smike_s  *
102211Smike_s  *
1030Sstevel@tonic-gate  * This routine builds the interface data structure from the data
1040Sstevel@tonic-gate  * already loaded during _symintOpen().
105211Smike_s  *
1060Sstevel@tonic-gate  * Prof:
107211Smike_s  *
1080Sstevel@tonic-gate  * 	1. Allocate a duplicate copy of the symbol table
109211Smike_s  *	   data.  (For Prof, a PROF_SYMBOL is just
110211Smike_s  *	   a structure containing an Elf32_Sym!)
111211Smike_s  *
1120Sstevel@tonic-gate  * 	2. Set internal parameters to reflect this.
113211Smike_s  *
114211Smike_s  *
1150Sstevel@tonic-gate  * Problems are dealt with by issuing an _err_exit().
116211Smike_s  *
1170Sstevel@tonic-gate  */
1180Sstevel@tonic-gate PROF_SYMBOL *
_symintLoad(PROF_FILE * proffilePtr)119211Smike_s _symintLoad(PROF_FILE *proffilePtr)
1200Sstevel@tonic-gate {
1213621Sab196087 	Elf_Data	*symdat_pri_p;
1223621Sab196087 	Elf_Data	*symdat_aux_p;
1233621Sab196087 	PROF_SYMBOL	*symlist;
1240Sstevel@tonic-gate 
1250Sstevel@tonic-gate 	DEBUG_LOC("_symintLoad: top");
1260Sstevel@tonic-gate 
1270Sstevel@tonic-gate 	profPtr = proffilePtr;
1280Sstevel@tonic-gate 
129211Smike_s 	/*
1300Sstevel@tonic-gate 	 * sanity checks.
1310Sstevel@tonic-gate 	 */
1320Sstevel@tonic-gate 	DEBUG_EXP(printf("profPtr = %x\n", profPtr));
1333621Sab196087 	DEBUG_EXP(printf("profPtr->pf_symdat_p = %x\n",
1343621Sab196087 	    profPtr->pf_symdat_pri_p));
1350Sstevel@tonic-gate 	DEBUG_EXP(printf("profPtr->pf_nstsyms = %x\n", profPtr->pf_nstsyms));
1360Sstevel@tonic-gate 
137211Smike_s 	assert(profPtr != 0);
1383621Sab196087 	assert(profPtr->pf_symdat_pri_p != 0);
139211Smike_s 	assert(profPtr->pf_nstsyms != 0);
1400Sstevel@tonic-gate 
1413621Sab196087 	symdat_pri_p = profPtr->pf_symdat_pri_p;
1423621Sab196087 	symdat_aux_p = profPtr->pf_symdat_aux_p;
1433621Sab196087 	DEBUG_EXP(printf("symdat_pri_p->d_size = %x\n", symdat_pri_p->d_size));
1440Sstevel@tonic-gate 
1453621Sab196087 	prstsym_size = (symdat_pri_p->d_size / profPtr->pf_nstsyms);
146211Smike_s 	DEBUG_EXP(printf("_symintLoad: prstsym_size = %d\n",
147211Smike_s 	    prstsym_size));
1480Sstevel@tonic-gate 
149211Smike_s 	/*
1500Sstevel@tonic-gate 	 * alloc a new copy of the array, and
1510Sstevel@tonic-gate 	 *  do a bit-wise copy since the structures
1520Sstevel@tonic-gate 	 *  ARE THE SAME SIZE & (effectively) HAVE THE SAME FIELDS!
1530Sstevel@tonic-gate 	 *  Set the descriptive `parameters' accordingly.
154211Smike_s 	 *
1553621Sab196087 	 * If there is an auxiliary symbol table (.SUNW_ldynsym) augmenting
1563621Sab196087 	 * the dynamic symbol table (.dynsym), then we copy both tables
1573621Sab196087 	 * into our copy, with the auxiliary coming first.
1583621Sab196087 	 *
1593621Sab196087 	 * (We'll take a copy, to simplify the 'Drop' logic.)
1600Sstevel@tonic-gate 	 */
1610Sstevel@tonic-gate 
1620Sstevel@tonic-gate 	{
1633621Sab196087 	size_t st_size;	/* size of symbol table data */
1640Sstevel@tonic-gate 
1653621Sab196087 	st_size = symdat_pri_p->d_size;
1663621Sab196087 	if (profPtr->pf_nstsyms_aux != 0)
1673621Sab196087 		st_size += symdat_aux_p->d_size;
1680Sstevel@tonic-gate 
1690Sstevel@tonic-gate 	NO_DEBUG_LOC("_symintLoad: before malloc for symbol list (PROF)");
1703621Sab196087 	prsym_list_p = symlist = (PROF_SYMBOL *)_Malloc(st_size, 1);
1710Sstevel@tonic-gate 	NO_DEBUG_LOC("_symintLoad: after malloc for symbol list (PROF)");
1720Sstevel@tonic-gate 
1733621Sab196087 	if (profPtr->pf_nstsyms_aux > 0) {
1743621Sab196087 		NO_DEBUG_LOC("_symintLoad: before memcpy for "
1753621Sab196087 		    "auxiliary symbol list (PROF)");
1763621Sab196087 		(void) memcpy(symlist, symdat_aux_p->d_buf,
1773621Sab196087 		    symdat_aux_p->d_size);
1783621Sab196087 		symlist += profPtr->pf_nstsyms_aux;
1793621Sab196087 	}
1803621Sab196087 
1810Sstevel@tonic-gate 	NO_DEBUG_LOC("_symintLoad: before memcpy for symbol list (PROF)");
1823621Sab196087 	(void) memcpy(symlist, symdat_pri_p->d_buf, symdat_pri_p->d_size);
1830Sstevel@tonic-gate 
1840Sstevel@tonic-gate 	profPtr->pf_nsyms = profPtr->pf_nstsyms;
1850Sstevel@tonic-gate 	}
1860Sstevel@tonic-gate 
1870Sstevel@tonic-gate 	DEBUG_LOC("_symintLoad: bottom");
188211Smike_s 	return (prsym_list_p);
1890Sstevel@tonic-gate }
190