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, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 23 /* 24 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 25 * Use is subject to license terms. 26 */ 27 28 #pragma ident "%Z%%M% %I% %E% SMI" 29 30 #include "gprof.h" 31 32 /* 33 * look up an address in a sorted-by-address namelist 34 * this deals with misses by mapping them to the next lower 35 * entry point. 36 */ 37 static int searchmsg = 0; /* Emit the diagnostic only once */ 38 39 nltype * 40 nllookup(mod_info_t *module, pctype address, pctype *nxtsym) 41 { 42 size_t low = 0, middle, high = module->nname - 1; 43 pctype keyval; 44 nltype *mnl = module->nl; 45 46 /* 47 * If this is the program executable in which we are looking up 48 * a symbol, then the actual load address will be the same as the 49 * address specified in the ELF file. For shared objects, the 50 * load address may differ from what is specified in the file. In 51 * this case, we may need to look for a different value altogether. 52 */ 53 keyval = module->txt_origin + (address - module->load_base); 54 55 if (keyval < mnl[low].value) { 56 if (nxtsym) { 57 *nxtsym = module->load_base + 58 (mnl[low].value - module->txt_origin); 59 } 60 return (NULL); 61 } 62 63 if (keyval >= mnl[high].value) { 64 if (nxtsym) 65 *nxtsym = module->load_end; 66 return (&mnl[high]); 67 } 68 69 while (low != high) { 70 middle = (high + low) >> 1; 71 72 if (mnl[middle].value <= keyval && 73 mnl[middle + 1].value > keyval) { 74 if (nxtsym) { 75 *nxtsym = module->load_base + 76 (mnl[middle + 1].value - 77 module->txt_origin); 78 } 79 return (&mnl[middle]); 80 } 81 82 if (mnl[middle].value > keyval) { 83 high = middle; 84 } else { 85 low = middle + 1; 86 } 87 } 88 89 if (searchmsg++ == 0) 90 (void) fprintf(stderr, "[nllookup] binary search fails???\n"); 91 92 /* must never reach here! */ 93 return (0); 94 } 95 96 arctype * 97 arclookup(nltype *parentp, nltype *childp) 98 { 99 arctype *arcp; 100 101 if (parentp == 0 || childp == 0) { 102 (void) fprintf(stderr, 103 "[arclookup] parentp == 0 || childp == 0\n"); 104 return (0); 105 } 106 #ifdef DEBUG 107 if (debug & LOOKUPDEBUG) { 108 (void) printf("[arclookup] parent %s child %s\n", 109 parentp->name, childp->name); 110 } 111 #endif /* DEBUG */ 112 113 for (arcp = parentp->children; arcp; arcp = arcp->arc_childlist) { 114 #ifdef DEBUG 115 if (debug & LOOKUPDEBUG) { 116 (void) printf( 117 "[arclookup]\t arc_parent %s arc_child %s\n", 118 arcp->arc_parentp->name, 119 arcp->arc_childp->name); 120 } 121 #endif /* DEBUG */ 122 if (arcp->arc_childp == childp) { 123 return (arcp); 124 } 125 } 126 return (0); 127 } 128