xref: /titanic_52/usr/src/cmd/sgs/prof/common/symintLoad.c (revision 1dd08564e4a3aafe66b00aee6f222b0885346fe8)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
57a5d89c4Sab196087  * Common Development and Distribution License (the "License").
67a5d89c4Sab196087  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
2192ed1782Smike_s 
2292ed1782Smike_s /*
23*1dd08564Sab196087  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
2492ed1782Smike_s  * Use is subject to license terms.
2592ed1782Smike_s  */
2692ed1782Smike_s 
277c478bd9Sstevel@tonic-gate /*	Copyright (c) 1988 AT&T	*/
287c478bd9Sstevel@tonic-gate /*	  All Rights Reserved  	*/
297c478bd9Sstevel@tonic-gate 
307c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
317c478bd9Sstevel@tonic-gate 
327c478bd9Sstevel@tonic-gate /*
337c478bd9Sstevel@tonic-gate  *	File: symintLoad.c
347c478bd9Sstevel@tonic-gate  *	Date: 12/15/88
357c478bd9Sstevel@tonic-gate  *
367c478bd9Sstevel@tonic-gate  *	This file provides code to build the profiling symbol array
377c478bd9Sstevel@tonic-gate  *	(array of PROF_SYMBOL).  This array contains all of the
387c478bd9Sstevel@tonic-gate  *	symbol table information plus selected debug information for
397c478bd9Sstevel@tonic-gate  *	each file and each function that has a coverage array.
407c478bd9Sstevel@tonic-gate  *
417c478bd9Sstevel@tonic-gate  *	The symbol table contains entries for every file, every
427c478bd9Sstevel@tonic-gate  *	function, and every coverage array.  The debug information
437c478bd9Sstevel@tonic-gate  *	has corresponding entries except that there are no entries
447c478bd9Sstevel@tonic-gate  *	for the coverage arrays.  (This may change later.)
457c478bd9Sstevel@tonic-gate  *
467c478bd9Sstevel@tonic-gate  *	The algorithm for building the profiling symbol array
477c478bd9Sstevel@tonic-gate  *	consists of scanning the symbol table for file, function,
487c478bd9Sstevel@tonic-gate  *	and coverage array entries and building an entry for each.
497c478bd9Sstevel@tonic-gate  *	The construction of an entry is constrained by the
507c478bd9Sstevel@tonic-gate  *	following factors:
517c478bd9Sstevel@tonic-gate  *
527c478bd9Sstevel@tonic-gate  *		- An entry is built for every file.
537c478bd9Sstevel@tonic-gate  *
547c478bd9Sstevel@tonic-gate  *		- An entry is built for a function only if there
557c478bd9Sstevel@tonic-gate  *		is a corresponding coverage array for the function.
567c478bd9Sstevel@tonic-gate  *
577c478bd9Sstevel@tonic-gate  *		- Entries must be ordered in the sense that each
587c478bd9Sstevel@tonic-gate  *		non-file entry points to its owner file and each
597c478bd9Sstevel@tonic-gate  *		file entry points to the next file (or null).
607c478bd9Sstevel@tonic-gate  *
617c478bd9Sstevel@tonic-gate  *		- The assembler specification (see C Issue 5 3B2
627c478bd9Sstevel@tonic-gate  *		Assembler System Test Specification by Howe, p. 28)
637c478bd9Sstevel@tonic-gate  *		states that all local symbols follow their file
647c478bd9Sstevel@tonic-gate  *		symbol in the symbol table.  This allows us to relate
657c478bd9Sstevel@tonic-gate  *		a function and its coverage array to the file that
667c478bd9Sstevel@tonic-gate  *		contains it.
677c478bd9Sstevel@tonic-gate  *
687c478bd9Sstevel@tonic-gate  *		- For each symbol included in the profiling symbol
697c478bd9Sstevel@tonic-gate  *		array, all corresponding symbol table information must
707c478bd9Sstevel@tonic-gate  *		be present together with selected debug information.
717c478bd9Sstevel@tonic-gate  *		Therefore, the correspondence between a symbol table
727c478bd9Sstevel@tonic-gate  *		entry and a debug entry must be established.
737c478bd9Sstevel@tonic-gate  *
747c478bd9Sstevel@tonic-gate  *		- Although duplicate (static) function names may appear,
757c478bd9Sstevel@tonic-gate  *		the names are unique within a given file.  Also, the
767c478bd9Sstevel@tonic-gate  *		value (address) of each function is included in both
777c478bd9Sstevel@tonic-gate  *		the symbol table information and the debug information.
787c478bd9Sstevel@tonic-gate  *		This provides a verifable correspondence between these
797c478bd9Sstevel@tonic-gate  *		information sets.
807c478bd9Sstevel@tonic-gate  *
817c478bd9Sstevel@tonic-gate  */
827c478bd9Sstevel@tonic-gate 
837c478bd9Sstevel@tonic-gate #include "string.h"
847c478bd9Sstevel@tonic-gate #include "symint.h"
857c478bd9Sstevel@tonic-gate #include "debug.h"
867c478bd9Sstevel@tonic-gate 
877c478bd9Sstevel@tonic-gate static PROF_FILE	*profPtr;
887c478bd9Sstevel@tonic-gate 
8992ed1782Smike_s /* LINTED: set but not used */
907c478bd9Sstevel@tonic-gate static int	prstsym_size;	/* size of a symbol table symbol */
917c478bd9Sstevel@tonic-gate 
9292ed1782Smike_s static PROF_SYMBOL	*prsym_list_p = 0;	/* the list to return. */
937c478bd9Sstevel@tonic-gate 
9492ed1782Smike_s /*
957c478bd9Sstevel@tonic-gate  * _symintLoad(proffilePtr)
967c478bd9Sstevel@tonic-gate  * proffilePtr	- PROF_FILE pointer returned by _symintOpen().
977c478bd9Sstevel@tonic-gate  *
987c478bd9Sstevel@tonic-gate  * returns PROF_SYMBOL * - pointer to the malloc-ed array of
997c478bd9Sstevel@tonic-gate  *			   symbol information entries, or
1007c478bd9Sstevel@tonic-gate  *			   NULL if fails.
1017c478bd9Sstevel@tonic-gate  *
1027c478bd9Sstevel@tonic-gate  *
1037c478bd9Sstevel@tonic-gate  * This routine builds the interface data structure from the data
1047c478bd9Sstevel@tonic-gate  * already loaded during _symintOpen().
1057c478bd9Sstevel@tonic-gate  *
1067c478bd9Sstevel@tonic-gate  * Prof:
1077c478bd9Sstevel@tonic-gate  *
1087c478bd9Sstevel@tonic-gate  * 	1. Allocate a duplicate copy of the symbol table
1097c478bd9Sstevel@tonic-gate  *	   data.  (For Prof, a PROF_SYMBOL is just
1107c478bd9Sstevel@tonic-gate  *	   a structure containing an Elf32_Sym!)
1117c478bd9Sstevel@tonic-gate  *
1127c478bd9Sstevel@tonic-gate  * 	2. Set internal parameters to reflect this.
1137c478bd9Sstevel@tonic-gate  *
1147c478bd9Sstevel@tonic-gate  *
1157c478bd9Sstevel@tonic-gate  * Problems are dealt with by issuing an _err_exit().
1167c478bd9Sstevel@tonic-gate  *
1177c478bd9Sstevel@tonic-gate  */
1187c478bd9Sstevel@tonic-gate PROF_SYMBOL *
11992ed1782Smike_s _symintLoad(PROF_FILE *proffilePtr)
1207c478bd9Sstevel@tonic-gate {
1217a5d89c4Sab196087 	Elf_Data	*symdat_pri_p;
1227a5d89c4Sab196087 	Elf_Data	*symdat_aux_p;
1237a5d89c4Sab196087 	PROF_SYMBOL	*symlist;
1247c478bd9Sstevel@tonic-gate 
1257c478bd9Sstevel@tonic-gate 	DEBUG_LOC("_symintLoad: top");
1267c478bd9Sstevel@tonic-gate 
1277c478bd9Sstevel@tonic-gate 	profPtr = proffilePtr;
1287c478bd9Sstevel@tonic-gate 
12992ed1782Smike_s 	/*
1307c478bd9Sstevel@tonic-gate 	 * sanity checks.
1317c478bd9Sstevel@tonic-gate 	 */
1327c478bd9Sstevel@tonic-gate 	DEBUG_EXP(printf("profPtr = %x\n", profPtr));
1337a5d89c4Sab196087 	DEBUG_EXP(printf("profPtr->pf_symdat_p = %x\n",
1347a5d89c4Sab196087 	    profPtr->pf_symdat_pri_p));
1357c478bd9Sstevel@tonic-gate 	DEBUG_EXP(printf("profPtr->pf_nstsyms = %x\n", profPtr->pf_nstsyms));
1367c478bd9Sstevel@tonic-gate 
1377c478bd9Sstevel@tonic-gate 	assert(profPtr != 0);
1387a5d89c4Sab196087 	assert(profPtr->pf_symdat_pri_p != 0);
1397c478bd9Sstevel@tonic-gate 	assert(profPtr->pf_nstsyms != 0);
1407c478bd9Sstevel@tonic-gate 
1417a5d89c4Sab196087 	symdat_pri_p = profPtr->pf_symdat_pri_p;
1427a5d89c4Sab196087 	symdat_aux_p = profPtr->pf_symdat_aux_p;
1437a5d89c4Sab196087 	DEBUG_EXP(printf("symdat_pri_p->d_size = %x\n", symdat_pri_p->d_size));
1447c478bd9Sstevel@tonic-gate 
1457a5d89c4Sab196087 	prstsym_size = (symdat_pri_p->d_size / profPtr->pf_nstsyms);
14692ed1782Smike_s 	DEBUG_EXP(printf("_symintLoad: prstsym_size = %d\n",
14792ed1782Smike_s 	    prstsym_size));
1487c478bd9Sstevel@tonic-gate 
14992ed1782Smike_s 	/*
1507c478bd9Sstevel@tonic-gate 	 * alloc a new copy of the array, and
1517c478bd9Sstevel@tonic-gate 	 *  do a bit-wise copy since the structures
1527c478bd9Sstevel@tonic-gate 	 *  ARE THE SAME SIZE & (effectively) HAVE THE SAME FIELDS!
1537c478bd9Sstevel@tonic-gate 	 *  Set the descriptive `parameters' accordingly.
1547c478bd9Sstevel@tonic-gate 	 *
1557a5d89c4Sab196087 	 * If there is an auxiliary symbol table (.SUNW_ldynsym) augmenting
1567a5d89c4Sab196087 	 * the dynamic symbol table (.dynsym), then we copy both tables
1577a5d89c4Sab196087 	 * into our copy, with the auxiliary coming first.
1587a5d89c4Sab196087 	 *
1597a5d89c4Sab196087 	 * (We'll take a copy, to simplify the 'Drop' logic.)
1607c478bd9Sstevel@tonic-gate 	 */
1617c478bd9Sstevel@tonic-gate 
1627c478bd9Sstevel@tonic-gate 	{
1637a5d89c4Sab196087 	size_t st_size;	/* size of symbol table data */
1647c478bd9Sstevel@tonic-gate 
1657a5d89c4Sab196087 	st_size = symdat_pri_p->d_size;
1667a5d89c4Sab196087 	if (profPtr->pf_nstsyms_aux != 0)
1677a5d89c4Sab196087 		st_size += symdat_aux_p->d_size;
1687c478bd9Sstevel@tonic-gate 
1697c478bd9Sstevel@tonic-gate 	NO_DEBUG_LOC("_symintLoad: before malloc for symbol list (PROF)");
1707a5d89c4Sab196087 	prsym_list_p = symlist = (PROF_SYMBOL *)_Malloc(st_size, 1);
1717c478bd9Sstevel@tonic-gate 	NO_DEBUG_LOC("_symintLoad: after malloc for symbol list (PROF)");
1727c478bd9Sstevel@tonic-gate 
1737a5d89c4Sab196087 	if (profPtr->pf_nstsyms_aux > 0) {
1747a5d89c4Sab196087 		NO_DEBUG_LOC("_symintLoad: before memcpy for "
1757a5d89c4Sab196087 		    "auxiliary symbol list (PROF)");
1767a5d89c4Sab196087 		(void) memcpy(symlist, symdat_aux_p->d_buf,
1777a5d89c4Sab196087 		    symdat_aux_p->d_size);
1787a5d89c4Sab196087 		symlist += profPtr->pf_nstsyms_aux;
1797a5d89c4Sab196087 	}
1807a5d89c4Sab196087 
1817c478bd9Sstevel@tonic-gate 	NO_DEBUG_LOC("_symintLoad: before memcpy for symbol list (PROF)");
1827a5d89c4Sab196087 	(void) memcpy(symlist, symdat_pri_p->d_buf, symdat_pri_p->d_size);
1837c478bd9Sstevel@tonic-gate 
1847c478bd9Sstevel@tonic-gate 	profPtr->pf_nsyms = profPtr->pf_nstsyms;
1857c478bd9Sstevel@tonic-gate 	}
1867c478bd9Sstevel@tonic-gate 
1877c478bd9Sstevel@tonic-gate 	DEBUG_LOC("_symintLoad: bottom");
1887c478bd9Sstevel@tonic-gate 	return (prsym_list_p);
1897c478bd9Sstevel@tonic-gate }
190