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