symintLoad.c revision 3621:2cbc0f92c696
1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22/*
23 * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
24 * Use is subject to license terms.
25 */
26
27/*	Copyright (c) 1988 AT&T	*/
28/*	  All Rights Reserved  	*/
29
30#pragma ident	"%Z%%M%	%I%	%E% SMI"
31
32/*
33 *	File: symintLoad.c
34 *	Date: 12/15/88
35 *
36 *	This file provides code to build the profiling symbol array
37 *	(array of PROF_SYMBOL).  This array contains all of the
38 *	symbol table information plus selected debug information for
39 *	each file and each function that has a coverage array.
40 *
41 *	The symbol table contains entries for every file, every
42 *	function, and every coverage array.  The debug information
43 *	has corresponding entries except that there are no entries
44 *	for the coverage arrays.  (This may change later.)
45 *
46 *	The algorithm for building the profiling symbol array
47 *	consists of scanning the symbol table for file, function,
48 *	and coverage array entries and building an entry for each.
49 *	The construction of an entry is constrained by the
50 *	following factors:
51 *
52 *		- An entry is built for every file.
53 *
54 *		- An entry is built for a function only if there
55 *		is a corresponding coverage array for the function.
56 *
57 *		- Entries must be ordered in the sense that each
58 *		non-file entry points to its owner file and each
59 *		file entry points to the next file (or null).
60 *
61 *		- The assembler specification (see C Issue 5 3B2
62 *		Assembler System Test Specification by Howe, p. 28)
63 *		states that all local symbols follow their file
64 *		symbol in the symbol table.  This allows us to relate
65 *		a function and its coverage array to the file that
66 *		contains it.
67 *
68 *		- For each symbol included in the profiling symbol
69 *		array, all corresponding symbol table information must
70 *		be present together with selected debug information.
71 *		Therefore, the correspondence between a symbol table
72 *		entry and a debug entry must be established.
73 *
74 *		- Although duplicate (static) function names may appear,
75 *		the names are unique within a given file.  Also, the
76 *		value (address) of each function is included in both
77 *		the symbol table information and the debug information.
78 *		This provides a verifable correspondence between these
79 *		information sets.
80 *
81 */
82
83#include "string.h"
84#include "symint.h"
85#include "debug.h"
86
87static PROF_FILE	*profPtr;
88
89/* LINTED: set but not used */
90static int	prstsym_size;	/* size of a symbol table symbol */
91
92static PROF_SYMBOL	*prsym_list_p = 0;	/* the list to return. */
93
94/*
95 * _symintLoad(proffilePtr)
96 * proffilePtr	- PROF_FILE pointer returned by _symintOpen().
97 *
98 * returns PROF_SYMBOL * - pointer to the malloc-ed array of
99 *			   symbol information entries, or
100 *			   NULL if fails.
101 *
102 *
103 * This routine builds the interface data structure from the data
104 * already loaded during _symintOpen().
105 *
106 * Prof:
107 *
108 * 	1. Allocate a duplicate copy of the symbol table
109 *	   data.  (For Prof, a PROF_SYMBOL is just
110 *	   a structure containing an Elf32_Sym!)
111 *
112 * 	2. Set internal parameters to reflect this.
113 *
114 *
115 * Problems are dealt with by issuing an _err_exit().
116 *
117 */
118PROF_SYMBOL *
119_symintLoad(PROF_FILE *proffilePtr)
120{
121	Elf_Data	*symdat_pri_p;
122	Elf_Data	*symdat_aux_p;
123	size_t		nsyms_pri;
124	PROF_SYMBOL	*symlist;
125
126	DEBUG_LOC("_symintLoad: top");
127
128	profPtr = proffilePtr;
129
130	/*
131	 * sanity checks.
132	 */
133	DEBUG_EXP(printf("profPtr = %x\n", profPtr));
134	DEBUG_EXP(printf("profPtr->pf_symdat_p = %x\n",
135	    profPtr->pf_symdat_pri_p));
136	DEBUG_EXP(printf("profPtr->pf_nstsyms = %x\n", profPtr->pf_nstsyms));
137
138	assert(profPtr != 0);
139	assert(profPtr->pf_symdat_pri_p != 0);
140	assert(profPtr->pf_nstsyms != 0);
141
142	symdat_pri_p = profPtr->pf_symdat_pri_p;
143	symdat_aux_p = profPtr->pf_symdat_aux_p;
144	nsyms_pri = profPtr->pf_nstsyms - profPtr->pf_nstsyms_aux;
145	DEBUG_EXP(printf("symdat_pri_p->d_size = %x\n", symdat_pri_p->d_size));
146
147	prstsym_size = (symdat_pri_p->d_size / profPtr->pf_nstsyms);
148	DEBUG_EXP(printf("_symintLoad: prstsym_size = %d\n",
149	    prstsym_size));
150
151	/*
152	 * alloc a new copy of the array, and
153	 *  do a bit-wise copy since the structures
154	 *  ARE THE SAME SIZE & (effectively) HAVE THE SAME FIELDS!
155	 *  Set the descriptive `parameters' accordingly.
156	 *
157	 * If there is an auxiliary symbol table (.SUNW_ldynsym) augmenting
158	 * the dynamic symbol table (.dynsym), then we copy both tables
159	 * into our copy, with the auxiliary coming first.
160	 *
161	 * (We'll take a copy, to simplify the 'Drop' logic.)
162	 */
163
164	{
165	size_t st_size;	/* size of symbol table data */
166
167	st_size = symdat_pri_p->d_size;
168	if (profPtr->pf_nstsyms_aux != 0)
169		st_size += symdat_aux_p->d_size;
170
171	NO_DEBUG_LOC("_symintLoad: before malloc for symbol list (PROF)");
172	prsym_list_p = symlist = (PROF_SYMBOL *)_Malloc(st_size, 1);
173	NO_DEBUG_LOC("_symintLoad: after malloc for symbol list (PROF)");
174
175	if (profPtr->pf_nstsyms_aux > 0) {
176		NO_DEBUG_LOC("_symintLoad: before memcpy for "
177		    "auxiliary symbol list (PROF)");
178		(void) memcpy(symlist, symdat_aux_p->d_buf,
179		    symdat_aux_p->d_size);
180		symlist += profPtr->pf_nstsyms_aux;
181	}
182
183	NO_DEBUG_LOC("_symintLoad: before memcpy for symbol list (PROF)");
184	(void) memcpy(symlist, symdat_pri_p->d_buf, symdat_pri_p->d_size);
185
186	profPtr->pf_nsyms = profPtr->pf_nstsyms;
187	}
188
189	DEBUG_LOC("_symintLoad: bottom");
190	return (prsym_list_p);
191}
192