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 87 static PROF_FILE *profPtr; 88 89 /* LINTED: set but not used */ 90 static int prstsym_size; /* size of a symbol table symbol */ 91 92 static 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 */ 118 PROF_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