1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate /* Copyright (c) 1988 AT&T */ 28*7c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 29*7c478bd9Sstevel@tonic-gate 30*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 31*7c478bd9Sstevel@tonic-gate 32*7c478bd9Sstevel@tonic-gate 33*7c478bd9Sstevel@tonic-gate /* ------------------------------------------------------------------------ */ 34*7c478bd9Sstevel@tonic-gate /* include headers */ 35*7c478bd9Sstevel@tonic-gate /* ------------------------------------------------------------------------ */ 36*7c478bd9Sstevel@tonic-gate 37*7c478bd9Sstevel@tonic-gate #include "static_prof.h" 38*7c478bd9Sstevel@tonic-gate 39*7c478bd9Sstevel@tonic-gate /* ========== elf_hash ==================================================== */ 40*7c478bd9Sstevel@tonic-gate /* 41*7c478bd9Sstevel@tonic-gate * DESCRIPTION: 42*7c478bd9Sstevel@tonic-gate * The hash function copied from libelf.so.1 43*7c478bd9Sstevel@tonic-gate */ 44*7c478bd9Sstevel@tonic-gate /* ======================================================================== */ 45*7c478bd9Sstevel@tonic-gate 46*7c478bd9Sstevel@tonic-gate static unsigned long 47*7c478bd9Sstevel@tonic-gate my_elf_hash(const char *name) 48*7c478bd9Sstevel@tonic-gate { 49*7c478bd9Sstevel@tonic-gate unsigned long g, h = 0; 50*7c478bd9Sstevel@tonic-gate const unsigned char *nm = (unsigned char *) name; 51*7c478bd9Sstevel@tonic-gate 52*7c478bd9Sstevel@tonic-gate while (*nm != '\0') { 53*7c478bd9Sstevel@tonic-gate h = (h << 4) + *nm++; 54*7c478bd9Sstevel@tonic-gate if ((g = h & MASK) != 0) 55*7c478bd9Sstevel@tonic-gate h ^= g >> 24; 56*7c478bd9Sstevel@tonic-gate h &= ~MASK; 57*7c478bd9Sstevel@tonic-gate } 58*7c478bd9Sstevel@tonic-gate return (h); 59*7c478bd9Sstevel@tonic-gate } 60*7c478bd9Sstevel@tonic-gate 61*7c478bd9Sstevel@tonic-gate /* ========== output_dtneeded ============================================= */ 62*7c478bd9Sstevel@tonic-gate /* 63*7c478bd9Sstevel@tonic-gate * DESCRIPTION: 64*7c478bd9Sstevel@tonic-gate * Outputs all the dt_needed entries if any. 65*7c478bd9Sstevel@tonic-gate */ 66*7c478bd9Sstevel@tonic-gate /* ======================================================================== */ 67*7c478bd9Sstevel@tonic-gate 68*7c478bd9Sstevel@tonic-gate static void 69*7c478bd9Sstevel@tonic-gate output_dtneeded(dt_list * list) 70*7c478bd9Sstevel@tonic-gate { 71*7c478bd9Sstevel@tonic-gate 72*7c478bd9Sstevel@tonic-gate dt_list *p = list; 73*7c478bd9Sstevel@tonic-gate 74*7c478bd9Sstevel@tonic-gate (void) fprintf(OUTPUT_FD, "#dtneeded:"); 75*7c478bd9Sstevel@tonic-gate if (!p) { 76*7c478bd9Sstevel@tonic-gate (void) fprintf(OUTPUT_FD, "\n"); 77*7c478bd9Sstevel@tonic-gate return; 78*7c478bd9Sstevel@tonic-gate } else { 79*7c478bd9Sstevel@tonic-gate while (p != NULL) { 80*7c478bd9Sstevel@tonic-gate (void) fprintf(OUTPUT_FD, 81*7c478bd9Sstevel@tonic-gate " %s", 82*7c478bd9Sstevel@tonic-gate p->libname); 83*7c478bd9Sstevel@tonic-gate p = p->next; 84*7c478bd9Sstevel@tonic-gate } 85*7c478bd9Sstevel@tonic-gate (void) fprintf(OUTPUT_FD, "\n"); 86*7c478bd9Sstevel@tonic-gate } 87*7c478bd9Sstevel@tonic-gate } 88*7c478bd9Sstevel@tonic-gate 89*7c478bd9Sstevel@tonic-gate /* ========== store_binding =============================================== */ 90*7c478bd9Sstevel@tonic-gate /* 91*7c478bd9Sstevel@tonic-gate * DESCRIPTION: 92*7c478bd9Sstevel@tonic-gate * Read in the symbol binding information from the symbol table and 93*7c478bd9Sstevel@tonic-gate * store them into the hash table of buckets. 94*7c478bd9Sstevel@tonic-gate */ 95*7c478bd9Sstevel@tonic-gate /* ======================================================================== */ 96*7c478bd9Sstevel@tonic-gate 97*7c478bd9Sstevel@tonic-gate static void 98*7c478bd9Sstevel@tonic-gate store_binding(binding_bucket * bind) 99*7c478bd9Sstevel@tonic-gate { 100*7c478bd9Sstevel@tonic-gate unsigned long bktno; 101*7c478bd9Sstevel@tonic-gate unsigned long orig_bktno; 102*7c478bd9Sstevel@tonic-gate int table_full = FALSE; 103*7c478bd9Sstevel@tonic-gate int i; 104*7c478bd9Sstevel@tonic-gate 105*7c478bd9Sstevel@tonic-gate bktno = my_elf_hash(bind->sym) % DEFBKTS; 106*7c478bd9Sstevel@tonic-gate orig_bktno = bktno; 107*7c478bd9Sstevel@tonic-gate 108*7c478bd9Sstevel@tonic-gate if (!bkts[bktno].sym) { 109*7c478bd9Sstevel@tonic-gate bkts[bktno].sym = bind->sym; 110*7c478bd9Sstevel@tonic-gate bkts[bktno].obj = bind->obj; 111*7c478bd9Sstevel@tonic-gate bkts[bktno].ref_lib = bind->ref_lib; 112*7c478bd9Sstevel@tonic-gate bkts[bktno].def_lib = bind->def_lib; 113*7c478bd9Sstevel@tonic-gate bkts[bktno].section = bind->section; 114*7c478bd9Sstevel@tonic-gate bkts[bktno].stbind = bind->stbind; 115*7c478bd9Sstevel@tonic-gate bkts[bktno].sttype = bind->sttype; 116*7c478bd9Sstevel@tonic-gate } else { 117*7c478bd9Sstevel@tonic-gate bktno = (bktno + 1) % DEFBKTS; 118*7c478bd9Sstevel@tonic-gate for (i = bktno; i < DEFBKTS; i = (i + 1) % DEFBKTS) { 119*7c478bd9Sstevel@tonic-gate if (i == orig_bktno) { 120*7c478bd9Sstevel@tonic-gate table_full = TRUE; 121*7c478bd9Sstevel@tonic-gate exit(1); 122*7c478bd9Sstevel@tonic-gate } 123*7c478bd9Sstevel@tonic-gate if (!bkts[i].sym) 124*7c478bd9Sstevel@tonic-gate break; 125*7c478bd9Sstevel@tonic-gate } 126*7c478bd9Sstevel@tonic-gate if ((!bkts[i].sym) && (table_full != TRUE)) { 127*7c478bd9Sstevel@tonic-gate bkts[i].sym = bind->sym; 128*7c478bd9Sstevel@tonic-gate bkts[i].obj = bind->obj; 129*7c478bd9Sstevel@tonic-gate bkts[i].ref_lib = bind->ref_lib; 130*7c478bd9Sstevel@tonic-gate bkts[i].def_lib = bind->def_lib; 131*7c478bd9Sstevel@tonic-gate bkts[i].section = bind->section; 132*7c478bd9Sstevel@tonic-gate bkts[i].stbind = bind->stbind; 133*7c478bd9Sstevel@tonic-gate bkts[i].sttype = bind->sttype; 134*7c478bd9Sstevel@tonic-gate } 135*7c478bd9Sstevel@tonic-gate } 136*7c478bd9Sstevel@tonic-gate } 137*7c478bd9Sstevel@tonic-gate 138*7c478bd9Sstevel@tonic-gate /* ========== check_store_binding ========================================= */ 139*7c478bd9Sstevel@tonic-gate /* 140*7c478bd9Sstevel@tonic-gate * DESCRIPTION: 141*7c478bd9Sstevel@tonic-gate * Check what's already on the hash table with the new symbol binding 142*7c478bd9Sstevel@tonic-gate * information from the dependencies and record it into the bucket. 143*7c478bd9Sstevel@tonic-gate */ 144*7c478bd9Sstevel@tonic-gate /* ======================================================================== */ 145*7c478bd9Sstevel@tonic-gate 146*7c478bd9Sstevel@tonic-gate static void 147*7c478bd9Sstevel@tonic-gate check_store_binding(binding_bucket * bind) 148*7c478bd9Sstevel@tonic-gate { 149*7c478bd9Sstevel@tonic-gate unsigned long bktno; 150*7c478bd9Sstevel@tonic-gate unsigned long orig_bktno; 151*7c478bd9Sstevel@tonic-gate unsigned long i; 152*7c478bd9Sstevel@tonic-gate 153*7c478bd9Sstevel@tonic-gate bktno = my_elf_hash(bind->sym) % DEFBKTS; 154*7c478bd9Sstevel@tonic-gate orig_bktno = bktno; 155*7c478bd9Sstevel@tonic-gate 156*7c478bd9Sstevel@tonic-gate if (!bkts[bktno].sym) 157*7c478bd9Sstevel@tonic-gate return; 158*7c478bd9Sstevel@tonic-gate if (bkts[bktno].sym && (strcmp(bkts[bktno].sym, bind->sym)) == 0) { 159*7c478bd9Sstevel@tonic-gate if (strcmp(bkts[bktno].ref_lib, "<Unknown>") == 0) 160*7c478bd9Sstevel@tonic-gate if (strcmp(bkts[bktno].obj, bind->obj)) 161*7c478bd9Sstevel@tonic-gate bkts[bktno].ref_lib = bind->obj; 162*7c478bd9Sstevel@tonic-gate } else { 163*7c478bd9Sstevel@tonic-gate bktno = (bktno + 1) % DEFBKTS; 164*7c478bd9Sstevel@tonic-gate for (i = bktno; i < DEFBKTS; i = (i + 1) % DEFBKTS) { 165*7c478bd9Sstevel@tonic-gate if (i == orig_bktno) 166*7c478bd9Sstevel@tonic-gate break; 167*7c478bd9Sstevel@tonic-gate if (!bkts[i].sym) 168*7c478bd9Sstevel@tonic-gate continue; 169*7c478bd9Sstevel@tonic-gate if (bkts[i].sym && 170*7c478bd9Sstevel@tonic-gate (strcmp(bkts[i].sym, bind->sym)) == 0) { 171*7c478bd9Sstevel@tonic-gate if (strcmp(bkts[i].ref_lib, "<Unknown>") == 0) 172*7c478bd9Sstevel@tonic-gate if (strcmp(bkts[i].obj, bind->obj)) 173*7c478bd9Sstevel@tonic-gate bkts[i].ref_lib = bind->obj; 174*7c478bd9Sstevel@tonic-gate break; 175*7c478bd9Sstevel@tonic-gate } 176*7c478bd9Sstevel@tonic-gate } 177*7c478bd9Sstevel@tonic-gate } 178*7c478bd9Sstevel@tonic-gate } 179*7c478bd9Sstevel@tonic-gate 180*7c478bd9Sstevel@tonic-gate /* ========== stringcompare =============================================== */ 181*7c478bd9Sstevel@tonic-gate /* 182*7c478bd9Sstevel@tonic-gate * DESCRIPTION: 183*7c478bd9Sstevel@tonic-gate * Compares two strings for qsort(). 184*7c478bd9Sstevel@tonic-gate */ 185*7c478bd9Sstevel@tonic-gate /* ======================================================================== */ 186*7c478bd9Sstevel@tonic-gate 187*7c478bd9Sstevel@tonic-gate static int 188*7c478bd9Sstevel@tonic-gate stringcompare(binding_bucket * a, 189*7c478bd9Sstevel@tonic-gate binding_bucket * b) 190*7c478bd9Sstevel@tonic-gate { 191*7c478bd9Sstevel@tonic-gate char *x = "\0"; 192*7c478bd9Sstevel@tonic-gate char *y = "\0"; 193*7c478bd9Sstevel@tonic-gate int retcode; 194*7c478bd9Sstevel@tonic-gate 195*7c478bd9Sstevel@tonic-gate if (a->sym) 196*7c478bd9Sstevel@tonic-gate x = a->sym; 197*7c478bd9Sstevel@tonic-gate 198*7c478bd9Sstevel@tonic-gate if (b->sym) 199*7c478bd9Sstevel@tonic-gate y = b->sym; 200*7c478bd9Sstevel@tonic-gate 201*7c478bd9Sstevel@tonic-gate retcode = strcoll(x, y); 202*7c478bd9Sstevel@tonic-gate return (retcode); 203*7c478bd9Sstevel@tonic-gate } 204*7c478bd9Sstevel@tonic-gate 205*7c478bd9Sstevel@tonic-gate /* ========== profile_binding ============================================= */ 206*7c478bd9Sstevel@tonic-gate /* 207*7c478bd9Sstevel@tonic-gate * DESCRIPTION: 208*7c478bd9Sstevel@tonic-gate * Output the bindings directly to stdout or a file. 209*7c478bd9Sstevel@tonic-gate */ 210*7c478bd9Sstevel@tonic-gate /* ======================================================================== */ 211*7c478bd9Sstevel@tonic-gate 212*7c478bd9Sstevel@tonic-gate static void 213*7c478bd9Sstevel@tonic-gate profile_binding(binding_bucket * bind) 214*7c478bd9Sstevel@tonic-gate { 215*7c478bd9Sstevel@tonic-gate char *ref_lib_ptr; 216*7c478bd9Sstevel@tonic-gate 217*7c478bd9Sstevel@tonic-gate if (bind->sym && strcmp(bind->ref_lib, "<Unknown>")) { 218*7c478bd9Sstevel@tonic-gate if (ref_lib_ptr = strrchr(bind->ref_lib, (int)'/')) { 219*7c478bd9Sstevel@tonic-gate ref_lib_ptr++; 220*7c478bd9Sstevel@tonic-gate if (bind->stbind) 221*7c478bd9Sstevel@tonic-gate (void) fprintf(OUTPUT_FD, 222*7c478bd9Sstevel@tonic-gate "%s|%s|%s|%s|%s|%s|%s\n", 223*7c478bd9Sstevel@tonic-gate ref_lib_ptr, 224*7c478bd9Sstevel@tonic-gate bind->section, 225*7c478bd9Sstevel@tonic-gate bind->stbind, 226*7c478bd9Sstevel@tonic-gate bind->sttype, 227*7c478bd9Sstevel@tonic-gate bind->sym, 228*7c478bd9Sstevel@tonic-gate bind->def_lib, 229*7c478bd9Sstevel@tonic-gate bind->obj); 230*7c478bd9Sstevel@tonic-gate } else if (bind->stbind) 231*7c478bd9Sstevel@tonic-gate (void) fprintf(OUTPUT_FD, 232*7c478bd9Sstevel@tonic-gate "%s|%s|%s|%s|%s|%s|%s\n", 233*7c478bd9Sstevel@tonic-gate bind->ref_lib, 234*7c478bd9Sstevel@tonic-gate bind->section, 235*7c478bd9Sstevel@tonic-gate bind->stbind, 236*7c478bd9Sstevel@tonic-gate bind->sttype, 237*7c478bd9Sstevel@tonic-gate bind->sym, 238*7c478bd9Sstevel@tonic-gate bind->def_lib, 239*7c478bd9Sstevel@tonic-gate bind->obj); 240*7c478bd9Sstevel@tonic-gate } else if (bind->sym && bind->stbind) 241*7c478bd9Sstevel@tonic-gate (void) fprintf(OUTPUT_FD, 242*7c478bd9Sstevel@tonic-gate "%s|%s|%s|%s|%s\n", 243*7c478bd9Sstevel@tonic-gate bind->obj, 244*7c478bd9Sstevel@tonic-gate bind->section, 245*7c478bd9Sstevel@tonic-gate bind->stbind, 246*7c478bd9Sstevel@tonic-gate bind->sttype, 247*7c478bd9Sstevel@tonic-gate bind->sym); 248*7c478bd9Sstevel@tonic-gate } 249*7c478bd9Sstevel@tonic-gate 250*7c478bd9Sstevel@tonic-gate /* ========== output_binding ============================================== */ 251*7c478bd9Sstevel@tonic-gate /* 252*7c478bd9Sstevel@tonic-gate * DESCRIPTION: 253*7c478bd9Sstevel@tonic-gate * Output the hash table to either stdout or a file. 254*7c478bd9Sstevel@tonic-gate */ 255*7c478bd9Sstevel@tonic-gate /* ======================================================================== */ 256*7c478bd9Sstevel@tonic-gate 257*7c478bd9Sstevel@tonic-gate static void 258*7c478bd9Sstevel@tonic-gate output_binding(char *prog_name, 259*7c478bd9Sstevel@tonic-gate char *target) 260*7c478bd9Sstevel@tonic-gate { 261*7c478bd9Sstevel@tonic-gate int i; 262*7c478bd9Sstevel@tonic-gate char *ref_lib_ptr; 263*7c478bd9Sstevel@tonic-gate 264*7c478bd9Sstevel@tonic-gate qsort(bkts, 265*7c478bd9Sstevel@tonic-gate DEFBKTS, 266*7c478bd9Sstevel@tonic-gate sizeof (binding_bucket), 267*7c478bd9Sstevel@tonic-gate (int (*) (const void *, const void *)) stringcompare); 268*7c478bd9Sstevel@tonic-gate 269*7c478bd9Sstevel@tonic-gate if (oflag) { 270*7c478bd9Sstevel@tonic-gate if ((OUTPUT_FD = fopen(outputfile, "w")) == NULL) { 271*7c478bd9Sstevel@tonic-gate if (sflag) 272*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 273*7c478bd9Sstevel@tonic-gate "\nfopen failed to open <%s>...\n\n", 274*7c478bd9Sstevel@tonic-gate outputfile); 275*7c478bd9Sstevel@tonic-gate exit(1); 276*7c478bd9Sstevel@tonic-gate } 277*7c478bd9Sstevel@tonic-gate } 278*7c478bd9Sstevel@tonic-gate /* generates profile report */ 279*7c478bd9Sstevel@tonic-gate (void) fprintf(OUTPUT_FD, 280*7c478bd9Sstevel@tonic-gate "#generated by %s\n", 281*7c478bd9Sstevel@tonic-gate prog_name); 282*7c478bd9Sstevel@tonic-gate (void) fprintf(OUTPUT_FD, 283*7c478bd9Sstevel@tonic-gate "#profiling symbols in .text section of %s\n", 284*7c478bd9Sstevel@tonic-gate target); 285*7c478bd9Sstevel@tonic-gate output_dtneeded(dt_needed); 286*7c478bd9Sstevel@tonic-gate 287*7c478bd9Sstevel@tonic-gate for (i = 0; i < DEFBKTS; i++) { 288*7c478bd9Sstevel@tonic-gate if (bkts[i].sym && strcmp(bkts[i].ref_lib, "<Unknown>")) { 289*7c478bd9Sstevel@tonic-gate if (ref_lib_ptr = strrchr(bkts[i].ref_lib, (int)'/')) { 290*7c478bd9Sstevel@tonic-gate ref_lib_ptr++; 291*7c478bd9Sstevel@tonic-gate if (bkts[i].stbind) 292*7c478bd9Sstevel@tonic-gate (void) fprintf(OUTPUT_FD, 293*7c478bd9Sstevel@tonic-gate "%s|%s|%s|%s|%s|%s|%s\n", 294*7c478bd9Sstevel@tonic-gate ref_lib_ptr, 295*7c478bd9Sstevel@tonic-gate bkts[i].section, 296*7c478bd9Sstevel@tonic-gate bkts[i].stbind, 297*7c478bd9Sstevel@tonic-gate bkts[i].sttype, 298*7c478bd9Sstevel@tonic-gate bkts[i].sym, 299*7c478bd9Sstevel@tonic-gate bkts[i].def_lib, 300*7c478bd9Sstevel@tonic-gate bkts[i].obj); 301*7c478bd9Sstevel@tonic-gate } else if (bkts[i].stbind) 302*7c478bd9Sstevel@tonic-gate (void) fprintf(OUTPUT_FD, 303*7c478bd9Sstevel@tonic-gate "%s|%s|%s|%s|%s|%s|%s\n", 304*7c478bd9Sstevel@tonic-gate bkts[i].ref_lib, 305*7c478bd9Sstevel@tonic-gate bkts[i].section, 306*7c478bd9Sstevel@tonic-gate bkts[i].stbind, 307*7c478bd9Sstevel@tonic-gate bkts[i].sttype, 308*7c478bd9Sstevel@tonic-gate bkts[i].sym, 309*7c478bd9Sstevel@tonic-gate bkts[i].def_lib, 310*7c478bd9Sstevel@tonic-gate bkts[i].obj); 311*7c478bd9Sstevel@tonic-gate } else if (bkts[i].sym && bkts[i].stbind) 312*7c478bd9Sstevel@tonic-gate (void) fprintf(OUTPUT_FD, 313*7c478bd9Sstevel@tonic-gate "%s|%s|%s|%s|%s\n", 314*7c478bd9Sstevel@tonic-gate bkts[i].obj, 315*7c478bd9Sstevel@tonic-gate bkts[i].section, 316*7c478bd9Sstevel@tonic-gate bkts[i].stbind, 317*7c478bd9Sstevel@tonic-gate bkts[i].sttype, 318*7c478bd9Sstevel@tonic-gate bkts[i].sym); 319*7c478bd9Sstevel@tonic-gate } 320*7c478bd9Sstevel@tonic-gate } 321*7c478bd9Sstevel@tonic-gate 322*7c478bd9Sstevel@tonic-gate /* ========== obj_init ==================================================== */ 323*7c478bd9Sstevel@tonic-gate /* 324*7c478bd9Sstevel@tonic-gate * DESCRIPTION: 325*7c478bd9Sstevel@tonic-gate * Open (object) file, get ELF descriptor, and verify that the file is 326*7c478bd9Sstevel@tonic-gate * an ELF file. 327*7c478bd9Sstevel@tonic-gate */ 328*7c478bd9Sstevel@tonic-gate /* ======================================================================== */ 329*7c478bd9Sstevel@tonic-gate 330*7c478bd9Sstevel@tonic-gate static int 331*7c478bd9Sstevel@tonic-gate obj_init(obj_list * c) 332*7c478bd9Sstevel@tonic-gate { 333*7c478bd9Sstevel@tonic-gate int mode = O_RDONLY; 334*7c478bd9Sstevel@tonic-gate 335*7c478bd9Sstevel@tonic-gate /* open the file */ 336*7c478bd9Sstevel@tonic-gate if ((c->obj->fd = open(c->obj->ename, mode)) < 0) { 337*7c478bd9Sstevel@tonic-gate if (sflag) { 338*7c478bd9Sstevel@tonic-gate if (errno == ENOENT) 339*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 340*7c478bd9Sstevel@tonic-gate "Cannot open <<%s>> : \ 341*7c478bd9Sstevel@tonic-gate No such file or directory.\n", 342*7c478bd9Sstevel@tonic-gate c->obj->ename); 343*7c478bd9Sstevel@tonic-gate else if (errno == EMFILE) 344*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 345*7c478bd9Sstevel@tonic-gate "File <<%s>> : Already opened.\n", 346*7c478bd9Sstevel@tonic-gate c->obj->ename); 347*7c478bd9Sstevel@tonic-gate } 348*7c478bd9Sstevel@tonic-gate c->obj->fd = NULL; 349*7c478bd9Sstevel@tonic-gate return (FAIL); 350*7c478bd9Sstevel@tonic-gate } 351*7c478bd9Sstevel@tonic-gate /* 352*7c478bd9Sstevel@tonic-gate * queries the ELF library's internal version. 353*7c478bd9Sstevel@tonic-gate * Passing ver equal to EV_NONE causes elf_version() to return 354*7c478bd9Sstevel@tonic-gate * the library's internal version, without altering the working 355*7c478bd9Sstevel@tonic-gate * version. If ver is a version known to the library, 356*7c478bd9Sstevel@tonic-gate * elf_version() returns the previous or initial working 357*7c478bd9Sstevel@tonic-gate * version number. Otherwise, the working version remains 358*7c478bd9Sstevel@tonic-gate * unchanged and elf_version() returns EV_NONE. 359*7c478bd9Sstevel@tonic-gate */ 360*7c478bd9Sstevel@tonic-gate 361*7c478bd9Sstevel@tonic-gate /* check if libelf.so is at the right level */ 362*7c478bd9Sstevel@tonic-gate if (elf_version(EV_CURRENT) == EV_NONE) { 363*7c478bd9Sstevel@tonic-gate if (sflag) 364*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 365*7c478bd9Sstevel@tonic-gate "Library out of date in ELF access routines.\n"); 366*7c478bd9Sstevel@tonic-gate return (FAIL); 367*7c478bd9Sstevel@tonic-gate } 368*7c478bd9Sstevel@tonic-gate /* 369*7c478bd9Sstevel@tonic-gate * Before the first call to elf_begin(), it must call 370*7c478bd9Sstevel@tonic-gate * elf_version() to coordinate versions. 371*7c478bd9Sstevel@tonic-gate */ 372*7c478bd9Sstevel@tonic-gate 373*7c478bd9Sstevel@tonic-gate /* 374*7c478bd9Sstevel@tonic-gate * get elf descriptor just to examine the contents of an existing 375*7c478bd9Sstevel@tonic-gate * file 376*7c478bd9Sstevel@tonic-gate */ 377*7c478bd9Sstevel@tonic-gate if ((c->obj->elf = elf_begin(c->obj->fd, ELF_C_READ, (Elf *) 0)) 378*7c478bd9Sstevel@tonic-gate == (Elf *) 0) { 379*7c478bd9Sstevel@tonic-gate if (sflag) 380*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 381*7c478bd9Sstevel@tonic-gate "File is not in executable and \ 382*7c478bd9Sstevel@tonic-gate linking format(ELF).\n"); 383*7c478bd9Sstevel@tonic-gate return (FAIL); 384*7c478bd9Sstevel@tonic-gate } 385*7c478bd9Sstevel@tonic-gate /* Rule out COFF, a.out and shell script files */ 386*7c478bd9Sstevel@tonic-gate if (elf_kind(c->obj->elf) == ELF_K_COFF) { 387*7c478bd9Sstevel@tonic-gate if (sflag) { 388*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 389*7c478bd9Sstevel@tonic-gate "File is not in executable \ 390*7c478bd9Sstevel@tonic-gate and linking format(ELF) or archive.\n"); 391*7c478bd9Sstevel@tonic-gate } 392*7c478bd9Sstevel@tonic-gate return (FAIL); 393*7c478bd9Sstevel@tonic-gate } 394*7c478bd9Sstevel@tonic-gate if (elf_kind(c->obj->elf) != ELF_K_AR && 395*7c478bd9Sstevel@tonic-gate elf_kind(c->obj->elf) != ELF_K_ELF) { 396*7c478bd9Sstevel@tonic-gate if (sflag) { 397*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 398*7c478bd9Sstevel@tonic-gate "File is not in executable and linking \ 399*7c478bd9Sstevel@tonic-gate format(ELF) or archive.\n"); 400*7c478bd9Sstevel@tonic-gate } 401*7c478bd9Sstevel@tonic-gate return (FAIL); 402*7c478bd9Sstevel@tonic-gate } 403*7c478bd9Sstevel@tonic-gate return (SUCCEED); 404*7c478bd9Sstevel@tonic-gate } 405*7c478bd9Sstevel@tonic-gate 406*7c478bd9Sstevel@tonic-gate /* ========== obj_elf_hdr ================================================= */ 407*7c478bd9Sstevel@tonic-gate /* 408*7c478bd9Sstevel@tonic-gate * DESCRIPTION: 409*7c478bd9Sstevel@tonic-gate * Obtain the elf header, verify elf header information 410*7c478bd9Sstevel@tonic-gate */ 411*7c478bd9Sstevel@tonic-gate /* ======================================================================== */ 412*7c478bd9Sstevel@tonic-gate 413*7c478bd9Sstevel@tonic-gate static int 414*7c478bd9Sstevel@tonic-gate obj_elf_hdr(obj_list * c) 415*7c478bd9Sstevel@tonic-gate { 416*7c478bd9Sstevel@tonic-gate #if defined(_LP64) 417*7c478bd9Sstevel@tonic-gate Elf64_Ehdr *ptr; 418*7c478bd9Sstevel@tonic-gate #else 419*7c478bd9Sstevel@tonic-gate Elf32_Ehdr *ptr; 420*7c478bd9Sstevel@tonic-gate #endif 421*7c478bd9Sstevel@tonic-gate 422*7c478bd9Sstevel@tonic-gate /* 423*7c478bd9Sstevel@tonic-gate * get the elf header if one is available for the ELF descriptor 424*7c478bd9Sstevel@tonic-gate * c->elf 425*7c478bd9Sstevel@tonic-gate */ 426*7c478bd9Sstevel@tonic-gate #if defined(_LP64) 427*7c478bd9Sstevel@tonic-gate if ((ptr = elf64_getehdr(c->obj->elf)) == (Elf64_Ehdr *) 0) { 428*7c478bd9Sstevel@tonic-gate if (sflag) 429*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 430*7c478bd9Sstevel@tonic-gate "File is not in 64-bit format.\n"); 431*7c478bd9Sstevel@tonic-gate return (FAIL); 432*7c478bd9Sstevel@tonic-gate } 433*7c478bd9Sstevel@tonic-gate #else 434*7c478bd9Sstevel@tonic-gate if ((ptr = elf32_getehdr(c->obj->elf)) == (Elf32_Ehdr *) 0) { 435*7c478bd9Sstevel@tonic-gate if (sflag) 436*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 437*7c478bd9Sstevel@tonic-gate "File is not in 32-bit format.\n"); 438*7c478bd9Sstevel@tonic-gate return (FAIL); 439*7c478bd9Sstevel@tonic-gate } 440*7c478bd9Sstevel@tonic-gate #endif 441*7c478bd9Sstevel@tonic-gate 442*7c478bd9Sstevel@tonic-gate /* if there is elf header, save the pointer */ 443*7c478bd9Sstevel@tonic-gate #if defined(_LP64) 444*7c478bd9Sstevel@tonic-gate c->obj->ehdr = (Elf64_Ehdr *) ptr; 445*7c478bd9Sstevel@tonic-gate #else 446*7c478bd9Sstevel@tonic-gate c->obj->ehdr = (Elf32_Ehdr *) ptr; 447*7c478bd9Sstevel@tonic-gate #endif 448*7c478bd9Sstevel@tonic-gate 449*7c478bd9Sstevel@tonic-gate /* e_ident[] is identification index which holds values */ 450*7c478bd9Sstevel@tonic-gate /* 451*7c478bd9Sstevel@tonic-gate * we could also use elf_getident() to retrieve file identification 452*7c478bd9Sstevel@tonic-gate * data. 453*7c478bd9Sstevel@tonic-gate */ 454*7c478bd9Sstevel@tonic-gate 455*7c478bd9Sstevel@tonic-gate /* 456*7c478bd9Sstevel@tonic-gate * e_ident[EI_CLASS] identifies the file's class: 457*7c478bd9Sstevel@tonic-gate * ELFCLASSNONE - invalid class 458*7c478bd9Sstevel@tonic-gate * ELFCLASS32 - 32-bit objects 459*7c478bd9Sstevel@tonic-gate * ELFCLASS64 - 64-bit objects 460*7c478bd9Sstevel@tonic-gate */ 461*7c478bd9Sstevel@tonic-gate 462*7c478bd9Sstevel@tonic-gate #if defined(_LP64) 463*7c478bd9Sstevel@tonic-gate if (ptr->e_ident[EI_CLASS] != ELFCLASS64) { 464*7c478bd9Sstevel@tonic-gate if (sflag) 465*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 466*7c478bd9Sstevel@tonic-gate "File is not in 64-bit format.\n"); 467*7c478bd9Sstevel@tonic-gate return (FAIL); 468*7c478bd9Sstevel@tonic-gate } 469*7c478bd9Sstevel@tonic-gate #else 470*7c478bd9Sstevel@tonic-gate if (ptr->e_ident[EI_CLASS] != ELFCLASS32) { 471*7c478bd9Sstevel@tonic-gate if (sflag) 472*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 473*7c478bd9Sstevel@tonic-gate "File is not in 32-bit format.\n"); 474*7c478bd9Sstevel@tonic-gate return (FAIL); 475*7c478bd9Sstevel@tonic-gate } 476*7c478bd9Sstevel@tonic-gate #endif 477*7c478bd9Sstevel@tonic-gate /* 478*7c478bd9Sstevel@tonic-gate * e_ident[EI_DATA] specifies the data encoding of the 479*7c478bd9Sstevel@tonic-gate * processor-specific data in the object file: 480*7c478bd9Sstevel@tonic-gate * ELFDATANONE - invalid data encoding 481*7c478bd9Sstevel@tonic-gate * ELFDATA2LSB - specifies 2's complement values, with the least 482*7c478bd9Sstevel@tonic-gate * significant byte occupying the lowest address 483*7c478bd9Sstevel@tonic-gate * ELFDATA2MSB - specifies 2's complement values, with the most 484*7c478bd9Sstevel@tonic-gate * significant byte occupying the lowest address 485*7c478bd9Sstevel@tonic-gate */ 486*7c478bd9Sstevel@tonic-gate 487*7c478bd9Sstevel@tonic-gate /* 488*7c478bd9Sstevel@tonic-gate * e_ident[EI_VERSION] specifies the ELF header version number. 489*7c478bd9Sstevel@tonic-gate * Currently, this value must be EV_CURRENT. 490*7c478bd9Sstevel@tonic-gate */ 491*7c478bd9Sstevel@tonic-gate 492*7c478bd9Sstevel@tonic-gate if (!(ptr->e_ident[EI_VERSION] == EV_CURRENT) && 493*7c478bd9Sstevel@tonic-gate (ptr->e_version == EV_CURRENT)) { 494*7c478bd9Sstevel@tonic-gate if (sflag) 495*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 496*7c478bd9Sstevel@tonic-gate "File is recorded in an \ 497*7c478bd9Sstevel@tonic-gate incompatible ELF version.\n"); 498*7c478bd9Sstevel@tonic-gate return (FAIL); 499*7c478bd9Sstevel@tonic-gate } 500*7c478bd9Sstevel@tonic-gate /* only interested in relocatable, shared object, or executable file */ 501*7c478bd9Sstevel@tonic-gate switch (ptr->e_type) { 502*7c478bd9Sstevel@tonic-gate case ET_REL: 503*7c478bd9Sstevel@tonic-gate case ET_EXEC: 504*7c478bd9Sstevel@tonic-gate case ET_DYN: 505*7c478bd9Sstevel@tonic-gate break; 506*7c478bd9Sstevel@tonic-gate default: 507*7c478bd9Sstevel@tonic-gate if (sflag) { 508*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 509*7c478bd9Sstevel@tonic-gate "File is not relocatable, "); 510*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 511*7c478bd9Sstevel@tonic-gate "executable, or shared object.\n"); 512*7c478bd9Sstevel@tonic-gate } 513*7c478bd9Sstevel@tonic-gate return (FAIL); 514*7c478bd9Sstevel@tonic-gate } 515*7c478bd9Sstevel@tonic-gate 516*7c478bd9Sstevel@tonic-gate /* 517*7c478bd9Sstevel@tonic-gate * e_machine's value specifies the required architecture for an 518*7c478bd9Sstevel@tonic-gate * individual file 519*7c478bd9Sstevel@tonic-gate */ 520*7c478bd9Sstevel@tonic-gate 521*7c478bd9Sstevel@tonic-gate #if defined(__sparcv9) 522*7c478bd9Sstevel@tonic-gate if (ptr->e_machine != EM_SPARCV9) { 523*7c478bd9Sstevel@tonic-gate if (sflag) 524*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 525*7c478bd9Sstevel@tonic-gate "File is not for 64-bit \ 526*7c478bd9Sstevel@tonic-gate SPARC machine architecture.\n"); 527*7c478bd9Sstevel@tonic-gate return (FAIL); 528*7c478bd9Sstevel@tonic-gate } 529*7c478bd9Sstevel@tonic-gate #elif defined(__amd64) 530*7c478bd9Sstevel@tonic-gate if (ptr->e_machine != EM_AMD64) { 531*7c478bd9Sstevel@tonic-gate if (sflag) 532*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 533*7c478bd9Sstevel@tonic-gate "File is not for 64-bit \ 534*7c478bd9Sstevel@tonic-gate amd64 machine architecture.\n"); 535*7c478bd9Sstevel@tonic-gate return (FAIL); 536*7c478bd9Sstevel@tonic-gate } 537*7c478bd9Sstevel@tonic-gate #elif defined(__i386) 538*7c478bd9Sstevel@tonic-gate if (ptr->e_machine != EM_386) { 539*7c478bd9Sstevel@tonic-gate if (sflag) 540*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 541*7c478bd9Sstevel@tonic-gate "File is not for 32-bit \ 542*7c478bd9Sstevel@tonic-gate i386 machine architecture.\n"); 543*7c478bd9Sstevel@tonic-gate return (FAIL); 544*7c478bd9Sstevel@tonic-gate } 545*7c478bd9Sstevel@tonic-gate #else 546*7c478bd9Sstevel@tonic-gate if (ptr->e_machine != EM_SPARC) { 547*7c478bd9Sstevel@tonic-gate if (sflag) 548*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 549*7c478bd9Sstevel@tonic-gate "File is not for 32-bit \ 550*7c478bd9Sstevel@tonic-gate SPARC machine architecture.\n"); 551*7c478bd9Sstevel@tonic-gate return (FAIL); 552*7c478bd9Sstevel@tonic-gate } 553*7c478bd9Sstevel@tonic-gate #endif 554*7c478bd9Sstevel@tonic-gate return (SUCCEED); 555*7c478bd9Sstevel@tonic-gate } 556*7c478bd9Sstevel@tonic-gate 557*7c478bd9Sstevel@tonic-gate /* ========== obj_prog_hdr ============================================= */ 558*7c478bd9Sstevel@tonic-gate /* 559*7c478bd9Sstevel@tonic-gate * DESCRIPTION: 560*7c478bd9Sstevel@tonic-gate * For executable files and shared objects only, check if it has 561*7c478bd9Sstevel@tonic-gate * a program header table. 562*7c478bd9Sstevel@tonic-gate */ 563*7c478bd9Sstevel@tonic-gate /* ===================================================================== */ 564*7c478bd9Sstevel@tonic-gate 565*7c478bd9Sstevel@tonic-gate static int 566*7c478bd9Sstevel@tonic-gate obj_prog_hdr(obj_list * c) 567*7c478bd9Sstevel@tonic-gate { 568*7c478bd9Sstevel@tonic-gate /* 569*7c478bd9Sstevel@tonic-gate * Assume: the elf header has already been read, and the file 570*7c478bd9Sstevel@tonic-gate * has already been determined to be 571*7c478bd9Sstevel@tonic-gate * executable, shared object, or relocatable 572*7c478bd9Sstevel@tonic-gate */ 573*7c478bd9Sstevel@tonic-gate 574*7c478bd9Sstevel@tonic-gate /* 575*7c478bd9Sstevel@tonic-gate * Program headers are meaningful only for executable and shared 576*7c478bd9Sstevel@tonic-gate * object files. It is an array of structures, each describing a 577*7c478bd9Sstevel@tonic-gate * segment or other information needs to prepare the program for 578*7c478bd9Sstevel@tonic-gate * execution. 579*7c478bd9Sstevel@tonic-gate */ 580*7c478bd9Sstevel@tonic-gate 581*7c478bd9Sstevel@tonic-gate /* skip if file is not executable or shared object */ 582*7c478bd9Sstevel@tonic-gate /* e_type == ET_REL meaning Relocatable file */ 583*7c478bd9Sstevel@tonic-gate if (c->obj->ehdr->e_type == ET_REL) 584*7c478bd9Sstevel@tonic-gate return (SUCCEED); 585*7c478bd9Sstevel@tonic-gate 586*7c478bd9Sstevel@tonic-gate /* 587*7c478bd9Sstevel@tonic-gate * ehdr->e_phoff holds the program header table's file offset in 588*7c478bd9Sstevel@tonic-gate * bytes. 589*7c478bd9Sstevel@tonic-gate */ 590*7c478bd9Sstevel@tonic-gate /* If the file has no program header table, this member holds zero. */ 591*7c478bd9Sstevel@tonic-gate /* 592*7c478bd9Sstevel@tonic-gate * ehdr->e_phnum holds the number of entries in the program header 593*7c478bd9Sstevel@tonic-gate * table. 594*7c478bd9Sstevel@tonic-gate */ 595*7c478bd9Sstevel@tonic-gate /* 596*7c478bd9Sstevel@tonic-gate * If a file has no program header table, e_phnum holds the value 597*7c478bd9Sstevel@tonic-gate * zero. 598*7c478bd9Sstevel@tonic-gate */ 599*7c478bd9Sstevel@tonic-gate 600*7c478bd9Sstevel@tonic-gate /* make sure there's a program header table */ 601*7c478bd9Sstevel@tonic-gate if ((c->obj->ehdr->e_phoff == 0) || 602*7c478bd9Sstevel@tonic-gate (c->obj->ehdr->e_phnum == 0)) { 603*7c478bd9Sstevel@tonic-gate if (sflag) 604*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 605*7c478bd9Sstevel@tonic-gate "File has no program header table.\n"); 606*7c478bd9Sstevel@tonic-gate return (FAIL); 607*7c478bd9Sstevel@tonic-gate } 608*7c478bd9Sstevel@tonic-gate return (SUCCEED); 609*7c478bd9Sstevel@tonic-gate } 610*7c478bd9Sstevel@tonic-gate 611*7c478bd9Sstevel@tonic-gate /* ========== find_dynamic_sect ========================================== */ 612*7c478bd9Sstevel@tonic-gate /* 613*7c478bd9Sstevel@tonic-gate * DESCRIPTION: 614*7c478bd9Sstevel@tonic-gate * Find the dynamic section. 615*7c478bd9Sstevel@tonic-gate */ 616*7c478bd9Sstevel@tonic-gate /* ======================================================================= */ 617*7c478bd9Sstevel@tonic-gate 618*7c478bd9Sstevel@tonic-gate static int 619*7c478bd9Sstevel@tonic-gate find_dynamic_sect(obj_list * c) 620*7c478bd9Sstevel@tonic-gate { 621*7c478bd9Sstevel@tonic-gate #if defined(_LP64) 622*7c478bd9Sstevel@tonic-gate Elf64_Shdr *scurrent; /* temp 64 bit section pointer */ 623*7c478bd9Sstevel@tonic-gate #else 624*7c478bd9Sstevel@tonic-gate Elf32_Shdr *scurrent; /* temp 32 bit section pointer */ 625*7c478bd9Sstevel@tonic-gate #endif 626*7c478bd9Sstevel@tonic-gate Elf_Scn *scn; /* temp section header pointer */ 627*7c478bd9Sstevel@tonic-gate Elf_Data *ddata; /* temp data header pointer */ 628*7c478bd9Sstevel@tonic-gate size_t index; /* temp section header table index */ 629*7c478bd9Sstevel@tonic-gate 630*7c478bd9Sstevel@tonic-gate c->obj->dynnames = NULL; /* init of dynamic string table ptr */ 631*7c478bd9Sstevel@tonic-gate c->obj->dynsect = NULL; /* init of dynamic section ptr */ 632*7c478bd9Sstevel@tonic-gate c->obj->ddata = NULL; /* init of dynamic strtab data ptr */ 633*7c478bd9Sstevel@tonic-gate 634*7c478bd9Sstevel@tonic-gate /* only process executables and shared objects */ 635*7c478bd9Sstevel@tonic-gate if (c->obj->ehdr->e_type != ET_EXEC && c->obj->ehdr->e_type != ET_DYN) 636*7c478bd9Sstevel@tonic-gate return (SUCCEED); 637*7c478bd9Sstevel@tonic-gate 638*7c478bd9Sstevel@tonic-gate if ((c->obj->ehdr->e_shoff == 0) || (c->obj->ehdr->e_shnum == 0)) { 639*7c478bd9Sstevel@tonic-gate /* there are no sections */ 640*7c478bd9Sstevel@tonic-gate return (SUCCEED); 641*7c478bd9Sstevel@tonic-gate } 642*7c478bd9Sstevel@tonic-gate /* search the section header table for dynamic section */ 643*7c478bd9Sstevel@tonic-gate 644*7c478bd9Sstevel@tonic-gate /* start with null section; section index = 0 */ 645*7c478bd9Sstevel@tonic-gate scn = 0; 646*7c478bd9Sstevel@tonic-gate 647*7c478bd9Sstevel@tonic-gate while ((scn = elf_nextscn(c->obj->elf, scn)) != 0) { 648*7c478bd9Sstevel@tonic-gate /* retrieve the section header */ 649*7c478bd9Sstevel@tonic-gate #if defined(_LP64) 650*7c478bd9Sstevel@tonic-gate scurrent = elf64_getshdr(scn); 651*7c478bd9Sstevel@tonic-gate #else 652*7c478bd9Sstevel@tonic-gate scurrent = elf32_getshdr(scn); 653*7c478bd9Sstevel@tonic-gate #endif 654*7c478bd9Sstevel@tonic-gate 655*7c478bd9Sstevel@tonic-gate /* check for dynamic section; (i.e., .dynamic) */ 656*7c478bd9Sstevel@tonic-gate if (scurrent->sh_type == SHT_DYNAMIC) { 657*7c478bd9Sstevel@tonic-gate ddata = 0; 658*7c478bd9Sstevel@tonic-gate if ((ddata = elf_getdata(scn, ddata)) == 0 || 659*7c478bd9Sstevel@tonic-gate (ddata->d_size == 0)) 660*7c478bd9Sstevel@tonic-gate return (SUCCEED); 661*7c478bd9Sstevel@tonic-gate 662*7c478bd9Sstevel@tonic-gate /* now, we got data of dynamic section */ 663*7c478bd9Sstevel@tonic-gate c->obj->dynsect = ddata->d_buf; 664*7c478bd9Sstevel@tonic-gate 665*7c478bd9Sstevel@tonic-gate /* index to section header for dynamic string table */ 666*7c478bd9Sstevel@tonic-gate index = scurrent->sh_link; 667*7c478bd9Sstevel@tonic-gate /* get scn descriptor of dynamic string table */ 668*7c478bd9Sstevel@tonic-gate scn = elf_getscn(c->obj->elf, index); 669*7c478bd9Sstevel@tonic-gate /* get dynamic string table section header */ 670*7c478bd9Sstevel@tonic-gate #if defined(_LP64) 671*7c478bd9Sstevel@tonic-gate scurrent = elf64_getshdr(scn); 672*7c478bd9Sstevel@tonic-gate #else 673*7c478bd9Sstevel@tonic-gate scurrent = elf32_getshdr(scn); 674*7c478bd9Sstevel@tonic-gate #endif 675*7c478bd9Sstevel@tonic-gate /* get the dynamic string table data descriptor */ 676*7c478bd9Sstevel@tonic-gate c->obj->ddata = elf_getdata(scn, (c->obj->ddata)); 677*7c478bd9Sstevel@tonic-gate /* save the pointer to dynamic string table data */ 678*7c478bd9Sstevel@tonic-gate c->obj->dynnames = c->obj->ddata->d_buf; 679*7c478bd9Sstevel@tonic-gate /* 680*7c478bd9Sstevel@tonic-gate * now, we got dynamic strtab and dynamic section 681*7c478bd9Sstevel@tonic-gate * information 682*7c478bd9Sstevel@tonic-gate */ 683*7c478bd9Sstevel@tonic-gate break; 684*7c478bd9Sstevel@tonic-gate } 685*7c478bd9Sstevel@tonic-gate } 686*7c478bd9Sstevel@tonic-gate return (SUCCEED); 687*7c478bd9Sstevel@tonic-gate } 688*7c478bd9Sstevel@tonic-gate 689*7c478bd9Sstevel@tonic-gate /* ========== find_symtabs ================================================ */ 690*7c478bd9Sstevel@tonic-gate /* 691*7c478bd9Sstevel@tonic-gate * DESCRIPTION: 692*7c478bd9Sstevel@tonic-gate * Find and check symbol tables for an application file 693*7c478bd9Sstevel@tonic-gate */ 694*7c478bd9Sstevel@tonic-gate /* ======================================================================== */ 695*7c478bd9Sstevel@tonic-gate 696*7c478bd9Sstevel@tonic-gate static int 697*7c478bd9Sstevel@tonic-gate find_symtabs(obj_list * c) 698*7c478bd9Sstevel@tonic-gate { 699*7c478bd9Sstevel@tonic-gate #if defined(_LP64) 700*7c478bd9Sstevel@tonic-gate Elf64_Shdr *shdr; 701*7c478bd9Sstevel@tonic-gate #else 702*7c478bd9Sstevel@tonic-gate Elf32_Shdr *shdr; 703*7c478bd9Sstevel@tonic-gate #endif 704*7c478bd9Sstevel@tonic-gate Elf_Scn *scn, *scn2; 705*7c478bd9Sstevel@tonic-gate Elf_Data *data; 706*7c478bd9Sstevel@tonic-gate 707*7c478bd9Sstevel@tonic-gate c->obj->sym_tab = NULL; 708*7c478bd9Sstevel@tonic-gate c->obj->sym_num = 0; 709*7c478bd9Sstevel@tonic-gate c->obj->sym_names = NULL; 710*7c478bd9Sstevel@tonic-gate c->obj->dsym_tab = NULL; 711*7c478bd9Sstevel@tonic-gate c->obj->dsym_num = 0; 712*7c478bd9Sstevel@tonic-gate c->obj->dsym_names = NULL; 713*7c478bd9Sstevel@tonic-gate c->obj->sym_data = NULL; 714*7c478bd9Sstevel@tonic-gate c->obj->dsym_data = NULL; 715*7c478bd9Sstevel@tonic-gate scn = 0; 716*7c478bd9Sstevel@tonic-gate 717*7c478bd9Sstevel@tonic-gate /* 718*7c478bd9Sstevel@tonic-gate * loop through the section header table looking for symbol tables. 719*7c478bd9Sstevel@tonic-gate * There must be one or two: .symtab and .dynsym 720*7c478bd9Sstevel@tonic-gate * upon finding a symbol table, save its pointer in obj_com. 721*7c478bd9Sstevel@tonic-gate */ 722*7c478bd9Sstevel@tonic-gate 723*7c478bd9Sstevel@tonic-gate /* get section descriptor */ 724*7c478bd9Sstevel@tonic-gate while ((scn = elf_nextscn(c->obj->elf, scn)) != 0) { 725*7c478bd9Sstevel@tonic-gate #if defined(_LP64) 726*7c478bd9Sstevel@tonic-gate Elf64_Sym *syms; 727*7c478bd9Sstevel@tonic-gate #else 728*7c478bd9Sstevel@tonic-gate Elf32_Sym *syms; 729*7c478bd9Sstevel@tonic-gate #endif 730*7c478bd9Sstevel@tonic-gate int symn; 731*7c478bd9Sstevel@tonic-gate char *strs; 732*7c478bd9Sstevel@tonic-gate 733*7c478bd9Sstevel@tonic-gate /* point to section header */ 734*7c478bd9Sstevel@tonic-gate #if defined(_LP64) 735*7c478bd9Sstevel@tonic-gate shdr = elf64_getshdr(scn); 736*7c478bd9Sstevel@tonic-gate #else 737*7c478bd9Sstevel@tonic-gate shdr = elf32_getshdr(scn); 738*7c478bd9Sstevel@tonic-gate #endif 739*7c478bd9Sstevel@tonic-gate 740*7c478bd9Sstevel@tonic-gate if (shdr == 0) 741*7c478bd9Sstevel@tonic-gate return (FAIL); 742*7c478bd9Sstevel@tonic-gate 743*7c478bd9Sstevel@tonic-gate /* skip if this section is not a symbol table */ 744*7c478bd9Sstevel@tonic-gate if ((shdr->sh_type != SHT_DYNSYM) && 745*7c478bd9Sstevel@tonic-gate (shdr->sh_type != SHT_SYMTAB)) 746*7c478bd9Sstevel@tonic-gate continue; 747*7c478bd9Sstevel@tonic-gate 748*7c478bd9Sstevel@tonic-gate /* get data descriptor for the symbol table itself */ 749*7c478bd9Sstevel@tonic-gate data = elf_getdata(scn, NULL); 750*7c478bd9Sstevel@tonic-gate if (data == NULL) 751*7c478bd9Sstevel@tonic-gate continue; 752*7c478bd9Sstevel@tonic-gate 753*7c478bd9Sstevel@tonic-gate /* save pointer to symbol table */ 754*7c478bd9Sstevel@tonic-gate #if defined(_LP64) 755*7c478bd9Sstevel@tonic-gate syms = (Elf64_Sym *) data->d_buf; 756*7c478bd9Sstevel@tonic-gate #else 757*7c478bd9Sstevel@tonic-gate syms = (Elf32_Sym *) data->d_buf; 758*7c478bd9Sstevel@tonic-gate #endif 759*7c478bd9Sstevel@tonic-gate 760*7c478bd9Sstevel@tonic-gate /* 761*7c478bd9Sstevel@tonic-gate * now start looking for the string table associated with 762*7c478bd9Sstevel@tonic-gate * this symbol table section 763*7c478bd9Sstevel@tonic-gate */ 764*7c478bd9Sstevel@tonic-gate 765*7c478bd9Sstevel@tonic-gate /* get section descriptor first */ 766*7c478bd9Sstevel@tonic-gate scn2 = elf_getscn(c->obj->elf, shdr->sh_link); 767*7c478bd9Sstevel@tonic-gate if (scn2 == NULL) 768*7c478bd9Sstevel@tonic-gate continue; 769*7c478bd9Sstevel@tonic-gate 770*7c478bd9Sstevel@tonic-gate /* get data descriptor for the string table section */ 771*7c478bd9Sstevel@tonic-gate data = elf_getdata(scn2, NULL); 772*7c478bd9Sstevel@tonic-gate if (data == NULL) 773*7c478bd9Sstevel@tonic-gate continue; 774*7c478bd9Sstevel@tonic-gate 775*7c478bd9Sstevel@tonic-gate /* save pointer to name string table */ 776*7c478bd9Sstevel@tonic-gate strs = data->d_buf; 777*7c478bd9Sstevel@tonic-gate symn = shdr->sh_size / shdr->sh_entsize; 778*7c478bd9Sstevel@tonic-gate 779*7c478bd9Sstevel@tonic-gate /* save information in obj_com */ 780*7c478bd9Sstevel@tonic-gate if (shdr->sh_type == SHT_SYMTAB) { 781*7c478bd9Sstevel@tonic-gate c->obj->sym_tab = syms; 782*7c478bd9Sstevel@tonic-gate c->obj->sym_num = symn; 783*7c478bd9Sstevel@tonic-gate c->obj->sym_names = strs; 784*7c478bd9Sstevel@tonic-gate c->obj->sym_data = data; 785*7c478bd9Sstevel@tonic-gate } else { /* must be the dynamic linking symbol table */ 786*7c478bd9Sstevel@tonic-gate c->obj->dsym_tab = syms; 787*7c478bd9Sstevel@tonic-gate c->obj->dsym_num = symn; 788*7c478bd9Sstevel@tonic-gate c->obj->dsym_names = strs; 789*7c478bd9Sstevel@tonic-gate c->obj->dsym_data = data; 790*7c478bd9Sstevel@tonic-gate } /* end if */ 791*7c478bd9Sstevel@tonic-gate } /* end while */ 792*7c478bd9Sstevel@tonic-gate return (SUCCEED); 793*7c478bd9Sstevel@tonic-gate } 794*7c478bd9Sstevel@tonic-gate 795*7c478bd9Sstevel@tonic-gate /* ========== obj_app_symtab ============================================== */ 796*7c478bd9Sstevel@tonic-gate /* 797*7c478bd9Sstevel@tonic-gate * DESCRIPTION: 798*7c478bd9Sstevel@tonic-gate * Check existence of application's symbol tables. 799*7c478bd9Sstevel@tonic-gate */ 800*7c478bd9Sstevel@tonic-gate /* ======================================================================== */ 801*7c478bd9Sstevel@tonic-gate 802*7c478bd9Sstevel@tonic-gate static int 803*7c478bd9Sstevel@tonic-gate obj_app_symtab(obj_list * c) 804*7c478bd9Sstevel@tonic-gate { 805*7c478bd9Sstevel@tonic-gate /* issue error if a relocatable file has no symbol table */ 806*7c478bd9Sstevel@tonic-gate if (c->obj->sym_tab == NULL) { 807*7c478bd9Sstevel@tonic-gate if (c->obj->ehdr->e_type == ET_REL) { 808*7c478bd9Sstevel@tonic-gate if (sflag) 809*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 810*7c478bd9Sstevel@tonic-gate "ELF error: no symbol \ 811*7c478bd9Sstevel@tonic-gate table in object file.\n"); 812*7c478bd9Sstevel@tonic-gate return (FAIL); 813*7c478bd9Sstevel@tonic-gate } else { 814*7c478bd9Sstevel@tonic-gate if (c->obj->dsym_tab == NULL) { 815*7c478bd9Sstevel@tonic-gate if (sflag) { 816*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 817*7c478bd9Sstevel@tonic-gate "Warning: Binary is \ 818*7c478bd9Sstevel@tonic-gate completely statically \ 819*7c478bd9Sstevel@tonic-gate linked and stripped.\n"); 820*7c478bd9Sstevel@tonic-gate } 821*7c478bd9Sstevel@tonic-gate return (FAIL); 822*7c478bd9Sstevel@tonic-gate } 823*7c478bd9Sstevel@tonic-gate if (sflag) 824*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 825*7c478bd9Sstevel@tonic-gate "Binary is stripped.\n"); 826*7c478bd9Sstevel@tonic-gate } 827*7c478bd9Sstevel@tonic-gate } 828*7c478bd9Sstevel@tonic-gate return (SUCCEED); 829*7c478bd9Sstevel@tonic-gate } 830*7c478bd9Sstevel@tonic-gate 831*7c478bd9Sstevel@tonic-gate /* ========== obj_finis =================================================== */ 832*7c478bd9Sstevel@tonic-gate /* 833*7c478bd9Sstevel@tonic-gate * DESCRIPTION: 834*7c478bd9Sstevel@tonic-gate * It checks the c->fd and c->elf pointers. If they are not NULL, 835*7c478bd9Sstevel@tonic-gate * close the file descriptor and ELF descriptor. 836*7c478bd9Sstevel@tonic-gate */ 837*7c478bd9Sstevel@tonic-gate /* ======================================================================== */ 838*7c478bd9Sstevel@tonic-gate 839*7c478bd9Sstevel@tonic-gate static void 840*7c478bd9Sstevel@tonic-gate obj_finis(obj_list * c) 841*7c478bd9Sstevel@tonic-gate { 842*7c478bd9Sstevel@tonic-gate obj_list *p; 843*7c478bd9Sstevel@tonic-gate 844*7c478bd9Sstevel@tonic-gate if (c) { 845*7c478bd9Sstevel@tonic-gate while (c) { 846*7c478bd9Sstevel@tonic-gate if (c->obj->elf != (Elf *) 0) 847*7c478bd9Sstevel@tonic-gate (void) elf_end(c->obj->elf); 848*7c478bd9Sstevel@tonic-gate if (c->obj->fd != 0) 849*7c478bd9Sstevel@tonic-gate (void) close(c->obj->fd); 850*7c478bd9Sstevel@tonic-gate p = c; 851*7c478bd9Sstevel@tonic-gate c = c->next; 852*7c478bd9Sstevel@tonic-gate free(p->obj); 853*7c478bd9Sstevel@tonic-gate free(p); 854*7c478bd9Sstevel@tonic-gate } 855*7c478bd9Sstevel@tonic-gate } 856*7c478bd9Sstevel@tonic-gate } 857*7c478bd9Sstevel@tonic-gate 858*7c478bd9Sstevel@tonic-gate /* ========= is_text_section ============================================== */ 859*7c478bd9Sstevel@tonic-gate /* 860*7c478bd9Sstevel@tonic-gate * DESCRIPTION: 861*7c478bd9Sstevel@tonic-gate * Scan through every section and returns TRUE(1) if the given section 862*7c478bd9Sstevel@tonic-gate * is ".text", otherwise, returns FALSE(0). 863*7c478bd9Sstevel@tonic-gate * INPUTS: shndx - section header index 864*7c478bd9Sstevel@tonic-gate * elf_file - ELF descriptor of the object file under test 865*7c478bd9Sstevel@tonic-gate * ehdr - ELF header of the object file under test 866*7c478bd9Sstevel@tonic-gate */ 867*7c478bd9Sstevel@tonic-gate /* ======================================================================== */ 868*7c478bd9Sstevel@tonic-gate 869*7c478bd9Sstevel@tonic-gate static int 870*7c478bd9Sstevel@tonic-gate is_text_section(int shndx, 871*7c478bd9Sstevel@tonic-gate Elf * elf_file, 872*7c478bd9Sstevel@tonic-gate #if defined(_LP64) 873*7c478bd9Sstevel@tonic-gate Elf64_Ehdr * ehdr) 874*7c478bd9Sstevel@tonic-gate #else 875*7c478bd9Sstevel@tonic-gate Elf32_Ehdr * ehdr) 876*7c478bd9Sstevel@tonic-gate #endif 877*7c478bd9Sstevel@tonic-gate { 878*7c478bd9Sstevel@tonic-gate char *sym_name; 879*7c478bd9Sstevel@tonic-gate Elf_Scn *scn = elf_getscn(elf_file, shndx); 880*7c478bd9Sstevel@tonic-gate 881*7c478bd9Sstevel@tonic-gate if (scn != NULL) { 882*7c478bd9Sstevel@tonic-gate #if defined(_LP64) 883*7c478bd9Sstevel@tonic-gate Elf64_Shdr *shdr; 884*7c478bd9Sstevel@tonic-gate shdr = elf64_getshdr(scn); 885*7c478bd9Sstevel@tonic-gate #else 886*7c478bd9Sstevel@tonic-gate Elf32_Shdr *shdr; 887*7c478bd9Sstevel@tonic-gate shdr = elf32_getshdr(scn); 888*7c478bd9Sstevel@tonic-gate #endif 889*7c478bd9Sstevel@tonic-gate sym_name = elf_strptr(elf_file, 890*7c478bd9Sstevel@tonic-gate ehdr->e_shstrndx, 891*7c478bd9Sstevel@tonic-gate shdr->sh_name); 892*7c478bd9Sstevel@tonic-gate if (strcmp(sym_name, ".text") == 0) 893*7c478bd9Sstevel@tonic-gate return (1); 894*7c478bd9Sstevel@tonic-gate } 895*7c478bd9Sstevel@tonic-gate return (0); 896*7c478bd9Sstevel@tonic-gate } 897*7c478bd9Sstevel@tonic-gate 898*7c478bd9Sstevel@tonic-gate /* ========== scan_archive_symbols ======================================= */ 899*7c478bd9Sstevel@tonic-gate /* 900*7c478bd9Sstevel@tonic-gate * DESCRIPTION: 901*7c478bd9Sstevel@tonic-gate * Scan through the archive symbol tables and write them out. 902*7c478bd9Sstevel@tonic-gate * INPUTS: syms - pointer to application symbol table 903*7c478bd9Sstevel@tonic-gate * symn - number of entries in application symbol table 904*7c478bd9Sstevel@tonic-gate * buf - first byte of application string table 905*7c478bd9Sstevel@tonic-gate */ 906*7c478bd9Sstevel@tonic-gate /* ======================================================================= */ 907*7c478bd9Sstevel@tonic-gate 908*7c478bd9Sstevel@tonic-gate static void 909*7c478bd9Sstevel@tonic-gate scan_archive_symbols(obj_list * c, 910*7c478bd9Sstevel@tonic-gate #if defined(_LP64) 911*7c478bd9Sstevel@tonic-gate Elf64_Sym * syms, 912*7c478bd9Sstevel@tonic-gate #else 913*7c478bd9Sstevel@tonic-gate Elf32_Sym * syms, 914*7c478bd9Sstevel@tonic-gate #endif 915*7c478bd9Sstevel@tonic-gate int symn, 916*7c478bd9Sstevel@tonic-gate char *buf, 917*7c478bd9Sstevel@tonic-gate Elf * elf_file, 918*7c478bd9Sstevel@tonic-gate #if defined(_LP64) 919*7c478bd9Sstevel@tonic-gate Elf64_Ehdr * ehdr) 920*7c478bd9Sstevel@tonic-gate #else 921*7c478bd9Sstevel@tonic-gate Elf32_Ehdr * ehdr) 922*7c478bd9Sstevel@tonic-gate #endif 923*7c478bd9Sstevel@tonic-gate { 924*7c478bd9Sstevel@tonic-gate #if defined(_LP64) 925*7c478bd9Sstevel@tonic-gate Elf64_Sym *symtab_entry; 926*7c478bd9Sstevel@tonic-gate #else 927*7c478bd9Sstevel@tonic-gate Elf32_Sym *symtab_entry; 928*7c478bd9Sstevel@tonic-gate #endif 929*7c478bd9Sstevel@tonic-gate int i; 930*7c478bd9Sstevel@tonic-gate char *sym_name; 931*7c478bd9Sstevel@tonic-gate int sttype; 932*7c478bd9Sstevel@tonic-gate int stbind; 933*7c478bd9Sstevel@tonic-gate 934*7c478bd9Sstevel@tonic-gate symtab_entry = syms; 935*7c478bd9Sstevel@tonic-gate for (i = 0; i < symn; i++, symtab_entry++) { 936*7c478bd9Sstevel@tonic-gate binding_bucket *binding; 937*7c478bd9Sstevel@tonic-gate /* look only at .text section symbols */ 938*7c478bd9Sstevel@tonic-gate if (!is_text_section(symtab_entry->st_shndx, elf_file, ehdr)) 939*7c478bd9Sstevel@tonic-gate continue; 940*7c478bd9Sstevel@tonic-gate 941*7c478bd9Sstevel@tonic-gate /* look only at weak and global symbols */ 942*7c478bd9Sstevel@tonic-gate #if defined(_LP64) 943*7c478bd9Sstevel@tonic-gate stbind = ELF64_ST_BIND(symtab_entry->st_info); 944*7c478bd9Sstevel@tonic-gate #else 945*7c478bd9Sstevel@tonic-gate stbind = ELF32_ST_BIND(symtab_entry->st_info); 946*7c478bd9Sstevel@tonic-gate #endif 947*7c478bd9Sstevel@tonic-gate if (stbind != STB_GLOBAL) { 948*7c478bd9Sstevel@tonic-gate if (stbind != STB_WEAK) 949*7c478bd9Sstevel@tonic-gate continue; 950*7c478bd9Sstevel@tonic-gate } 951*7c478bd9Sstevel@tonic-gate /* look only at functions and objects */ 952*7c478bd9Sstevel@tonic-gate #if defined(_LP64) 953*7c478bd9Sstevel@tonic-gate sttype = ELF64_ST_TYPE(symtab_entry->st_info); 954*7c478bd9Sstevel@tonic-gate #else 955*7c478bd9Sstevel@tonic-gate sttype = ELF32_ST_TYPE(symtab_entry->st_info); 956*7c478bd9Sstevel@tonic-gate #endif 957*7c478bd9Sstevel@tonic-gate if (sttype != STT_FUNC) { 958*7c478bd9Sstevel@tonic-gate if (sttype != STT_OBJECT) 959*7c478bd9Sstevel@tonic-gate continue; 960*7c478bd9Sstevel@tonic-gate } 961*7c478bd9Sstevel@tonic-gate sym_name = buf + symtab_entry->st_name; 962*7c478bd9Sstevel@tonic-gate binding = (struct binding_bucket *) 963*7c478bd9Sstevel@tonic-gate malloc(sizeof (binding_bucket)); 964*7c478bd9Sstevel@tonic-gate binding->sym = sym_name; 965*7c478bd9Sstevel@tonic-gate binding->obj = c->obj->ename; 966*7c478bd9Sstevel@tonic-gate binding->section = "TEXT"; 967*7c478bd9Sstevel@tonic-gate binding->ref_lib = "<Unknown>"; 968*7c478bd9Sstevel@tonic-gate binding->def_lib = "*DIRECT*"; 969*7c478bd9Sstevel@tonic-gate if (stbind == STB_GLOBAL) 970*7c478bd9Sstevel@tonic-gate binding->stbind = "GLOB"; 971*7c478bd9Sstevel@tonic-gate else if (stbind == STB_WEAK) 972*7c478bd9Sstevel@tonic-gate binding->stbind = "WEAK"; 973*7c478bd9Sstevel@tonic-gate if (sttype == STT_FUNC) 974*7c478bd9Sstevel@tonic-gate binding->sttype = "FUNC"; 975*7c478bd9Sstevel@tonic-gate else if (sttype == STT_OBJECT) 976*7c478bd9Sstevel@tonic-gate binding->sttype = "OBJT"; 977*7c478bd9Sstevel@tonic-gate if (pflag) 978*7c478bd9Sstevel@tonic-gate profile_binding(binding); 979*7c478bd9Sstevel@tonic-gate else 980*7c478bd9Sstevel@tonic-gate store_binding(binding); 981*7c478bd9Sstevel@tonic-gate } /* end for */ 982*7c478bd9Sstevel@tonic-gate } 983*7c478bd9Sstevel@tonic-gate 984*7c478bd9Sstevel@tonic-gate /* ========== scan_symbols ================================================ */ 985*7c478bd9Sstevel@tonic-gate /* 986*7c478bd9Sstevel@tonic-gate * DESCRIPTION: 987*7c478bd9Sstevel@tonic-gate * Scan through the symbol table and write them out. 988*7c478bd9Sstevel@tonic-gate * INPUTS: syms - pointer to application symbol table 989*7c478bd9Sstevel@tonic-gate * symn - number of entries in application symbol table 990*7c478bd9Sstevel@tonic-gate * buf - first byte of application string table 991*7c478bd9Sstevel@tonic-gate */ 992*7c478bd9Sstevel@tonic-gate /* ======================================================================== */ 993*7c478bd9Sstevel@tonic-gate 994*7c478bd9Sstevel@tonic-gate static void 995*7c478bd9Sstevel@tonic-gate scan_symbols(obj_list * c, 996*7c478bd9Sstevel@tonic-gate #if defined(_LP64) 997*7c478bd9Sstevel@tonic-gate Elf64_Sym * syms, 998*7c478bd9Sstevel@tonic-gate #else 999*7c478bd9Sstevel@tonic-gate Elf32_Sym * syms, 1000*7c478bd9Sstevel@tonic-gate #endif 1001*7c478bd9Sstevel@tonic-gate int symn, 1002*7c478bd9Sstevel@tonic-gate char *buf) 1003*7c478bd9Sstevel@tonic-gate { 1004*7c478bd9Sstevel@tonic-gate #if defined(_LP64) 1005*7c478bd9Sstevel@tonic-gate Elf64_Sym *symtab_entry; 1006*7c478bd9Sstevel@tonic-gate #else 1007*7c478bd9Sstevel@tonic-gate Elf32_Sym *symtab_entry; 1008*7c478bd9Sstevel@tonic-gate #endif 1009*7c478bd9Sstevel@tonic-gate int i; 1010*7c478bd9Sstevel@tonic-gate char *sym_name; 1011*7c478bd9Sstevel@tonic-gate int sttype; 1012*7c478bd9Sstevel@tonic-gate int stbind; 1013*7c478bd9Sstevel@tonic-gate 1014*7c478bd9Sstevel@tonic-gate symtab_entry = syms; 1015*7c478bd9Sstevel@tonic-gate if (pflag) { 1016*7c478bd9Sstevel@tonic-gate (void) fprintf(OUTPUT_FD, 1017*7c478bd9Sstevel@tonic-gate "#profiling symbols in .text section of %s\n", 1018*7c478bd9Sstevel@tonic-gate c->obj->ename); 1019*7c478bd9Sstevel@tonic-gate output_dtneeded(dt_needed); 1020*7c478bd9Sstevel@tonic-gate } 1021*7c478bd9Sstevel@tonic-gate for (i = 0; i < symn; i++, symtab_entry++) { 1022*7c478bd9Sstevel@tonic-gate binding_bucket *binding; 1023*7c478bd9Sstevel@tonic-gate /* look only at .text section symbols */ 1024*7c478bd9Sstevel@tonic-gate if (!is_text_section(symtab_entry->st_shndx, 1025*7c478bd9Sstevel@tonic-gate c->obj->elf, 1026*7c478bd9Sstevel@tonic-gate c->obj->ehdr)) 1027*7c478bd9Sstevel@tonic-gate continue; 1028*7c478bd9Sstevel@tonic-gate 1029*7c478bd9Sstevel@tonic-gate /* look only at weak and global symbols */ 1030*7c478bd9Sstevel@tonic-gate #if defined(_LP64) 1031*7c478bd9Sstevel@tonic-gate stbind = ELF64_ST_BIND(symtab_entry->st_info); 1032*7c478bd9Sstevel@tonic-gate #else 1033*7c478bd9Sstevel@tonic-gate stbind = ELF32_ST_BIND(symtab_entry->st_info); 1034*7c478bd9Sstevel@tonic-gate #endif 1035*7c478bd9Sstevel@tonic-gate if (stbind != STB_GLOBAL) { 1036*7c478bd9Sstevel@tonic-gate if (stbind != STB_WEAK) 1037*7c478bd9Sstevel@tonic-gate continue; 1038*7c478bd9Sstevel@tonic-gate } 1039*7c478bd9Sstevel@tonic-gate /* look only at functions and objects */ 1040*7c478bd9Sstevel@tonic-gate #if defined(_LP64) 1041*7c478bd9Sstevel@tonic-gate sttype = ELF64_ST_TYPE(symtab_entry->st_info); 1042*7c478bd9Sstevel@tonic-gate #else 1043*7c478bd9Sstevel@tonic-gate sttype = ELF32_ST_TYPE(symtab_entry->st_info); 1044*7c478bd9Sstevel@tonic-gate #endif 1045*7c478bd9Sstevel@tonic-gate if (sttype != STT_FUNC) { 1046*7c478bd9Sstevel@tonic-gate if (sttype != STT_OBJECT) 1047*7c478bd9Sstevel@tonic-gate continue; 1048*7c478bd9Sstevel@tonic-gate } 1049*7c478bd9Sstevel@tonic-gate sym_name = buf + symtab_entry->st_name; 1050*7c478bd9Sstevel@tonic-gate binding = (struct binding_bucket *) 1051*7c478bd9Sstevel@tonic-gate malloc(sizeof (binding_bucket)); 1052*7c478bd9Sstevel@tonic-gate binding->sym = sym_name; 1053*7c478bd9Sstevel@tonic-gate binding->obj = c->obj->ename; 1054*7c478bd9Sstevel@tonic-gate binding->section = "TEXT"; 1055*7c478bd9Sstevel@tonic-gate binding->ref_lib = "<Unknown>"; 1056*7c478bd9Sstevel@tonic-gate binding->def_lib = "*DIRECT*"; 1057*7c478bd9Sstevel@tonic-gate if (stbind == STB_GLOBAL) 1058*7c478bd9Sstevel@tonic-gate binding->stbind = "GLOB"; 1059*7c478bd9Sstevel@tonic-gate else if (stbind == STB_WEAK) 1060*7c478bd9Sstevel@tonic-gate binding->stbind = "WEAK"; 1061*7c478bd9Sstevel@tonic-gate if (sttype == STT_FUNC) 1062*7c478bd9Sstevel@tonic-gate binding->sttype = "FUNC"; 1063*7c478bd9Sstevel@tonic-gate else if (sttype == STT_OBJECT) 1064*7c478bd9Sstevel@tonic-gate binding->sttype = "OBJT"; 1065*7c478bd9Sstevel@tonic-gate if (pflag) 1066*7c478bd9Sstevel@tonic-gate profile_binding(binding); 1067*7c478bd9Sstevel@tonic-gate else 1068*7c478bd9Sstevel@tonic-gate store_binding(binding); 1069*7c478bd9Sstevel@tonic-gate } /* end for */ 1070*7c478bd9Sstevel@tonic-gate } 1071*7c478bd9Sstevel@tonic-gate 1072*7c478bd9Sstevel@tonic-gate /* ========= bind_symbols ================================================= */ 1073*7c478bd9Sstevel@tonic-gate /* 1074*7c478bd9Sstevel@tonic-gate * DESCRIPTION: 1075*7c478bd9Sstevel@tonic-gate * Scan through the dynamic symbol table and write them out. 1076*7c478bd9Sstevel@tonic-gate * INPUTS: syms - pointer to application symbol table 1077*7c478bd9Sstevel@tonic-gate * symn - number of entries in application symbol table 1078*7c478bd9Sstevel@tonic-gate * buf - first byte of application string table 1079*7c478bd9Sstevel@tonic-gate */ 1080*7c478bd9Sstevel@tonic-gate /* ======================================================================== */ 1081*7c478bd9Sstevel@tonic-gate 1082*7c478bd9Sstevel@tonic-gate static void 1083*7c478bd9Sstevel@tonic-gate bind_symbols(obj_list * c, 1084*7c478bd9Sstevel@tonic-gate #if defined(_LP64) 1085*7c478bd9Sstevel@tonic-gate Elf64_Sym * syms, 1086*7c478bd9Sstevel@tonic-gate #else 1087*7c478bd9Sstevel@tonic-gate Elf32_Sym * syms, 1088*7c478bd9Sstevel@tonic-gate #endif 1089*7c478bd9Sstevel@tonic-gate int symn, 1090*7c478bd9Sstevel@tonic-gate char *buf) 1091*7c478bd9Sstevel@tonic-gate { 1092*7c478bd9Sstevel@tonic-gate #if defined(_LP64) 1093*7c478bd9Sstevel@tonic-gate Elf64_Sym *symtab_entry; 1094*7c478bd9Sstevel@tonic-gate #else 1095*7c478bd9Sstevel@tonic-gate Elf32_Sym *symtab_entry; 1096*7c478bd9Sstevel@tonic-gate #endif 1097*7c478bd9Sstevel@tonic-gate int i; 1098*7c478bd9Sstevel@tonic-gate char *sym_name; 1099*7c478bd9Sstevel@tonic-gate binding_bucket *binding; 1100*7c478bd9Sstevel@tonic-gate int sttype; 1101*7c478bd9Sstevel@tonic-gate int stbind; 1102*7c478bd9Sstevel@tonic-gate 1103*7c478bd9Sstevel@tonic-gate symtab_entry = syms; 1104*7c478bd9Sstevel@tonic-gate for (i = 0; i < symn; i++, symtab_entry++) { 1105*7c478bd9Sstevel@tonic-gate /* look only at global symbols */ 1106*7c478bd9Sstevel@tonic-gate #if defined(_LP64) 1107*7c478bd9Sstevel@tonic-gate stbind = ELF64_ST_BIND(symtab_entry->st_info); 1108*7c478bd9Sstevel@tonic-gate #else 1109*7c478bd9Sstevel@tonic-gate stbind = ELF32_ST_BIND(symtab_entry->st_info); 1110*7c478bd9Sstevel@tonic-gate #endif 1111*7c478bd9Sstevel@tonic-gate if (symtab_entry->st_shndx == SHN_UNDEF) 1112*7c478bd9Sstevel@tonic-gate continue; 1113*7c478bd9Sstevel@tonic-gate if (symtab_entry->st_shndx == SHN_ABS) 1114*7c478bd9Sstevel@tonic-gate continue; 1115*7c478bd9Sstevel@tonic-gate if (stbind != STB_GLOBAL) { 1116*7c478bd9Sstevel@tonic-gate if (stbind != STB_WEAK) 1117*7c478bd9Sstevel@tonic-gate continue; 1118*7c478bd9Sstevel@tonic-gate } 1119*7c478bd9Sstevel@tonic-gate /* look only at functions and objects */ 1120*7c478bd9Sstevel@tonic-gate #if defined(_LP64) 1121*7c478bd9Sstevel@tonic-gate sttype = ELF64_ST_TYPE(symtab_entry->st_info); 1122*7c478bd9Sstevel@tonic-gate #else 1123*7c478bd9Sstevel@tonic-gate sttype = ELF32_ST_TYPE(symtab_entry->st_info); 1124*7c478bd9Sstevel@tonic-gate #endif 1125*7c478bd9Sstevel@tonic-gate if (sttype != STT_FUNC) { 1126*7c478bd9Sstevel@tonic-gate if (sttype != STT_OBJECT) 1127*7c478bd9Sstevel@tonic-gate continue; 1128*7c478bd9Sstevel@tonic-gate } 1129*7c478bd9Sstevel@tonic-gate sym_name = buf + symtab_entry->st_name; 1130*7c478bd9Sstevel@tonic-gate binding = (binding_bucket *) malloc(sizeof (binding_bucket)); 1131*7c478bd9Sstevel@tonic-gate binding->obj = c->obj->ename; 1132*7c478bd9Sstevel@tonic-gate binding->sym = sym_name; 1133*7c478bd9Sstevel@tonic-gate if (!pflag) 1134*7c478bd9Sstevel@tonic-gate check_store_binding(binding); 1135*7c478bd9Sstevel@tonic-gate } /* end for */ 1136*7c478bd9Sstevel@tonic-gate } 1137*7c478bd9Sstevel@tonic-gate 1138*7c478bd9Sstevel@tonic-gate /* ========== get_scnfd =================================================== */ 1139*7c478bd9Sstevel@tonic-gate /* 1140*7c478bd9Sstevel@tonic-gate * DESCRIPTION: 1141*7c478bd9Sstevel@tonic-gate * Gets section descriptor for the associated string table 1142*7c478bd9Sstevel@tonic-gate * and verifies that the type of the section pointed to is 1143*7c478bd9Sstevel@tonic-gate * indeed of type STRTAB. Returns a valid section descriptor 1144*7c478bd9Sstevel@tonic-gate * or NULL on error. 1145*7c478bd9Sstevel@tonic-gate */ 1146*7c478bd9Sstevel@tonic-gate /* ======================================================================== */ 1147*7c478bd9Sstevel@tonic-gate 1148*7c478bd9Sstevel@tonic-gate static Elf_Scn * 1149*7c478bd9Sstevel@tonic-gate get_scnfd(Elf * e_file, 1150*7c478bd9Sstevel@tonic-gate int shstrtab, 1151*7c478bd9Sstevel@tonic-gate int SCN_TYPE) 1152*7c478bd9Sstevel@tonic-gate { 1153*7c478bd9Sstevel@tonic-gate Elf_Scn *scn_fd; 1154*7c478bd9Sstevel@tonic-gate #if defined(_LP64) 1155*7c478bd9Sstevel@tonic-gate Elf64_Shdr *shdr; 1156*7c478bd9Sstevel@tonic-gate #else 1157*7c478bd9Sstevel@tonic-gate Elf32_Shdr *shdr; 1158*7c478bd9Sstevel@tonic-gate #endif 1159*7c478bd9Sstevel@tonic-gate 1160*7c478bd9Sstevel@tonic-gate if ((scn_fd = elf_getscn(e_file, shstrtab)) == NULL) 1161*7c478bd9Sstevel@tonic-gate return (NULL); 1162*7c478bd9Sstevel@tonic-gate 1163*7c478bd9Sstevel@tonic-gate #if defined(_LP64) 1164*7c478bd9Sstevel@tonic-gate shdr = elf64_getshdr(scn_fd); 1165*7c478bd9Sstevel@tonic-gate #else 1166*7c478bd9Sstevel@tonic-gate shdr = elf32_getshdr(scn_fd); 1167*7c478bd9Sstevel@tonic-gate #endif 1168*7c478bd9Sstevel@tonic-gate 1169*7c478bd9Sstevel@tonic-gate if (shdr->sh_type != SCN_TYPE) 1170*7c478bd9Sstevel@tonic-gate return (NULL); 1171*7c478bd9Sstevel@tonic-gate return (scn_fd); 1172*7c478bd9Sstevel@tonic-gate } 1173*7c478bd9Sstevel@tonic-gate 1174*7c478bd9Sstevel@tonic-gate /* ========== print_symtab ================================================ */ 1175*7c478bd9Sstevel@tonic-gate /* 1176*7c478bd9Sstevel@tonic-gate * DESCRIPTION: 1177*7c478bd9Sstevel@tonic-gate * Outputs symbol bindings from symbol table to hash table. 1178*7c478bd9Sstevel@tonic-gate */ 1179*7c478bd9Sstevel@tonic-gate /* ======================================================================== */ 1180*7c478bd9Sstevel@tonic-gate 1181*7c478bd9Sstevel@tonic-gate static void 1182*7c478bd9Sstevel@tonic-gate print_symtab(obj_list * com, 1183*7c478bd9Sstevel@tonic-gate Elf * elf_file, 1184*7c478bd9Sstevel@tonic-gate #if defined(_LP64) 1185*7c478bd9Sstevel@tonic-gate Elf64_Ehdr * ehdr, 1186*7c478bd9Sstevel@tonic-gate Elf64_Shdr * shdr, 1187*7c478bd9Sstevel@tonic-gate #else 1188*7c478bd9Sstevel@tonic-gate Elf32_Ehdr * ehdr, 1189*7c478bd9Sstevel@tonic-gate Elf32_Shdr * shdr, 1190*7c478bd9Sstevel@tonic-gate #endif 1191*7c478bd9Sstevel@tonic-gate Elf_Scn * p_sd, 1192*7c478bd9Sstevel@tonic-gate char *filename) 1193*7c478bd9Sstevel@tonic-gate { 1194*7c478bd9Sstevel@tonic-gate #if defined(_LP64) 1195*7c478bd9Sstevel@tonic-gate Elf64_Sym *syms; 1196*7c478bd9Sstevel@tonic-gate #else 1197*7c478bd9Sstevel@tonic-gate Elf32_Sym *syms; 1198*7c478bd9Sstevel@tonic-gate #endif 1199*7c478bd9Sstevel@tonic-gate Elf_Data *data; 1200*7c478bd9Sstevel@tonic-gate Elf_Scn *scn; 1201*7c478bd9Sstevel@tonic-gate int count = 0; 1202*7c478bd9Sstevel@tonic-gate char *strs, *fullname; 1203*7c478bd9Sstevel@tonic-gate obj_list *c; 1204*7c478bd9Sstevel@tonic-gate 1205*7c478bd9Sstevel@tonic-gate c = (obj_list *) malloc(sizeof (obj_list)); 1206*7c478bd9Sstevel@tonic-gate c->obj = (obj_com *) malloc(sizeof (obj_com)); 1207*7c478bd9Sstevel@tonic-gate fullname = (char *)malloc(strlen(com->obj->ename) 1208*7c478bd9Sstevel@tonic-gate + strlen(filename) + 2); 1209*7c478bd9Sstevel@tonic-gate (void *) strcpy(fullname, com->obj->ename); 1210*7c478bd9Sstevel@tonic-gate (void *) strcat(fullname, "("); 1211*7c478bd9Sstevel@tonic-gate (void *) strcat(fullname, filename); 1212*7c478bd9Sstevel@tonic-gate (void *) strcat(fullname, ")"); 1213*7c478bd9Sstevel@tonic-gate c->obj->ename = fullname; 1214*7c478bd9Sstevel@tonic-gate 1215*7c478bd9Sstevel@tonic-gate if ((data = elf_getdata(p_sd, NULL)) == NULL) { 1216*7c478bd9Sstevel@tonic-gate if (sflag) 1217*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 1218*7c478bd9Sstevel@tonic-gate "%s - No symbol table data\n", 1219*7c478bd9Sstevel@tonic-gate c->obj->ename); 1220*7c478bd9Sstevel@tonic-gate return; 1221*7c478bd9Sstevel@tonic-gate } 1222*7c478bd9Sstevel@tonic-gate #if defined(_LP64) 1223*7c478bd9Sstevel@tonic-gate syms = (Elf64_Sym *) data->d_buf; 1224*7c478bd9Sstevel@tonic-gate #else 1225*7c478bd9Sstevel@tonic-gate syms = (Elf32_Sym *) data->d_buf; 1226*7c478bd9Sstevel@tonic-gate #endif 1227*7c478bd9Sstevel@tonic-gate 1228*7c478bd9Sstevel@tonic-gate scn = elf_getscn(elf_file, shdr->sh_link); 1229*7c478bd9Sstevel@tonic-gate if (scn == NULL) 1230*7c478bd9Sstevel@tonic-gate return; 1231*7c478bd9Sstevel@tonic-gate data = elf_getdata(scn, NULL); 1232*7c478bd9Sstevel@tonic-gate if (data == NULL) 1233*7c478bd9Sstevel@tonic-gate return; 1234*7c478bd9Sstevel@tonic-gate strs = data->d_buf; 1235*7c478bd9Sstevel@tonic-gate count = shdr->sh_size / shdr->sh_entsize; 1236*7c478bd9Sstevel@tonic-gate if (syms == NULL) { 1237*7c478bd9Sstevel@tonic-gate if (sflag) 1238*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 1239*7c478bd9Sstevel@tonic-gate "%s: Problem reading symbol data\n", 1240*7c478bd9Sstevel@tonic-gate c->obj->ename); 1241*7c478bd9Sstevel@tonic-gate return; 1242*7c478bd9Sstevel@tonic-gate } 1243*7c478bd9Sstevel@tonic-gate c->obj->sym_tab = syms; 1244*7c478bd9Sstevel@tonic-gate c->obj->sym_num = count; 1245*7c478bd9Sstevel@tonic-gate c->obj->sym_names = strs; 1246*7c478bd9Sstevel@tonic-gate 1247*7c478bd9Sstevel@tonic-gate if (aflag) 1248*7c478bd9Sstevel@tonic-gate (void) scan_archive_symbols(c, 1249*7c478bd9Sstevel@tonic-gate c->obj->sym_tab, 1250*7c478bd9Sstevel@tonic-gate c->obj->sym_num, 1251*7c478bd9Sstevel@tonic-gate c->obj->sym_names, 1252*7c478bd9Sstevel@tonic-gate elf_file, 1253*7c478bd9Sstevel@tonic-gate ehdr); 1254*7c478bd9Sstevel@tonic-gate else 1255*7c478bd9Sstevel@tonic-gate (void) bind_symbols(c, 1256*7c478bd9Sstevel@tonic-gate c->obj->sym_tab, 1257*7c478bd9Sstevel@tonic-gate c->obj->sym_num, 1258*7c478bd9Sstevel@tonic-gate c->obj->sym_names); 1259*7c478bd9Sstevel@tonic-gate free(c->obj); 1260*7c478bd9Sstevel@tonic-gate free(c); 1261*7c478bd9Sstevel@tonic-gate } 1262*7c478bd9Sstevel@tonic-gate 1263*7c478bd9Sstevel@tonic-gate /* ========== get_symtab ================================================== */ 1264*7c478bd9Sstevel@tonic-gate /* 1265*7c478bd9Sstevel@tonic-gate * DESCRIPTION: 1266*7c478bd9Sstevel@tonic-gate * Gets the symbol table. This function does not output the contents 1267*7c478bd9Sstevel@tonic-gate * of the symbol table but sets up the parameters and then calls 1268*7c478bd9Sstevel@tonic-gate * print_symtab() to output the symbol bindings. 1269*7c478bd9Sstevel@tonic-gate */ 1270*7c478bd9Sstevel@tonic-gate /* ======================================================================== */ 1271*7c478bd9Sstevel@tonic-gate 1272*7c478bd9Sstevel@tonic-gate static void 1273*7c478bd9Sstevel@tonic-gate get_symtab(obj_list * c, 1274*7c478bd9Sstevel@tonic-gate Elf * elf_file, 1275*7c478bd9Sstevel@tonic-gate #if defined(_LP64) 1276*7c478bd9Sstevel@tonic-gate Elf64_Ehdr * ehdr, 1277*7c478bd9Sstevel@tonic-gate #else 1278*7c478bd9Sstevel@tonic-gate Elf32_Ehdr * ehdr, 1279*7c478bd9Sstevel@tonic-gate #endif 1280*7c478bd9Sstevel@tonic-gate char *filename) 1281*7c478bd9Sstevel@tonic-gate { 1282*7c478bd9Sstevel@tonic-gate Elf_Scn *scn, *scnfd; 1283*7c478bd9Sstevel@tonic-gate Elf_Data *data; 1284*7c478bd9Sstevel@tonic-gate #if defined(_LP64) 1285*7c478bd9Sstevel@tonic-gate Elf64_Word symtabtype; 1286*7c478bd9Sstevel@tonic-gate #else 1287*7c478bd9Sstevel@tonic-gate Elf32_Word symtabtype; 1288*7c478bd9Sstevel@tonic-gate #endif 1289*7c478bd9Sstevel@tonic-gate 1290*7c478bd9Sstevel@tonic-gate /* get section header string table */ 1291*7c478bd9Sstevel@tonic-gate scnfd = get_scnfd(elf_file, ehdr->e_shstrndx, SHT_STRTAB); 1292*7c478bd9Sstevel@tonic-gate if (scnfd == NULL) { 1293*7c478bd9Sstevel@tonic-gate if (sflag) 1294*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 1295*7c478bd9Sstevel@tonic-gate "%s: Could not get string table\n", 1296*7c478bd9Sstevel@tonic-gate filename); 1297*7c478bd9Sstevel@tonic-gate return; 1298*7c478bd9Sstevel@tonic-gate } 1299*7c478bd9Sstevel@tonic-gate data = elf_getdata(scnfd, NULL); 1300*7c478bd9Sstevel@tonic-gate if (data->d_size == 0) { 1301*7c478bd9Sstevel@tonic-gate if (sflag) 1302*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 1303*7c478bd9Sstevel@tonic-gate "%s: No data in string table\n", 1304*7c478bd9Sstevel@tonic-gate filename); 1305*7c478bd9Sstevel@tonic-gate return; 1306*7c478bd9Sstevel@tonic-gate } 1307*7c478bd9Sstevel@tonic-gate symtabtype = SHT_SYMTAB; 1308*7c478bd9Sstevel@tonic-gate scn = 0; 1309*7c478bd9Sstevel@tonic-gate while ((scn = elf_nextscn(elf_file, scn)) != 0) { 1310*7c478bd9Sstevel@tonic-gate #if defined(_LP64) 1311*7c478bd9Sstevel@tonic-gate Elf64_Shdr *shdr; 1312*7c478bd9Sstevel@tonic-gate if ((shdr = elf64_getshdr(scn)) == NULL) 1313*7c478bd9Sstevel@tonic-gate #else 1314*7c478bd9Sstevel@tonic-gate Elf32_Shdr *shdr; 1315*7c478bd9Sstevel@tonic-gate if ((shdr = elf32_getshdr(scn)) == NULL) 1316*7c478bd9Sstevel@tonic-gate #endif 1317*7c478bd9Sstevel@tonic-gate { 1318*7c478bd9Sstevel@tonic-gate if (sflag) 1319*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 1320*7c478bd9Sstevel@tonic-gate "%s: %s:\n", 1321*7c478bd9Sstevel@tonic-gate filename, 1322*7c478bd9Sstevel@tonic-gate elf_errmsg(-1)); 1323*7c478bd9Sstevel@tonic-gate return; 1324*7c478bd9Sstevel@tonic-gate } 1325*7c478bd9Sstevel@tonic-gate if (shdr->sh_type == symtabtype) 1326*7c478bd9Sstevel@tonic-gate print_symtab(c, elf_file, ehdr, shdr, scn, filename); 1327*7c478bd9Sstevel@tonic-gate } /* end while */ 1328*7c478bd9Sstevel@tonic-gate } 1329*7c478bd9Sstevel@tonic-gate 1330*7c478bd9Sstevel@tonic-gate /* ========== process ===================================================== */ 1331*7c478bd9Sstevel@tonic-gate /* 1332*7c478bd9Sstevel@tonic-gate * DESCRIPTION: 1333*7c478bd9Sstevel@tonic-gate * Gets the ELF header and, if it exists, call get_symtab() to begin 1334*7c478bd9Sstevel@tonic-gate * processing of the file; otherwise, returns with a warning. 1335*7c478bd9Sstevel@tonic-gate */ 1336*7c478bd9Sstevel@tonic-gate /* ======================================================================== */ 1337*7c478bd9Sstevel@tonic-gate 1338*7c478bd9Sstevel@tonic-gate static void 1339*7c478bd9Sstevel@tonic-gate process(obj_list * c, 1340*7c478bd9Sstevel@tonic-gate Elf * elf_file, 1341*7c478bd9Sstevel@tonic-gate char *filename) 1342*7c478bd9Sstevel@tonic-gate { 1343*7c478bd9Sstevel@tonic-gate #if defined(_LP64) 1344*7c478bd9Sstevel@tonic-gate Elf64_Ehdr *ehdr; 1345*7c478bd9Sstevel@tonic-gate #else 1346*7c478bd9Sstevel@tonic-gate Elf32_Ehdr *ehdr; 1347*7c478bd9Sstevel@tonic-gate #endif 1348*7c478bd9Sstevel@tonic-gate 1349*7c478bd9Sstevel@tonic-gate #if defined(_LP64) 1350*7c478bd9Sstevel@tonic-gate if ((ehdr = elf64_getehdr(elf_file)) == NULL) 1351*7c478bd9Sstevel@tonic-gate #else 1352*7c478bd9Sstevel@tonic-gate if ((ehdr = elf32_getehdr(elf_file)) == NULL) 1353*7c478bd9Sstevel@tonic-gate #endif 1354*7c478bd9Sstevel@tonic-gate { 1355*7c478bd9Sstevel@tonic-gate if (sflag) 1356*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 1357*7c478bd9Sstevel@tonic-gate "%s: %s\n", 1358*7c478bd9Sstevel@tonic-gate filename, elf_errmsg(-1)); 1359*7c478bd9Sstevel@tonic-gate return; 1360*7c478bd9Sstevel@tonic-gate } 1361*7c478bd9Sstevel@tonic-gate get_symtab(c, elf_file, ehdr, filename); 1362*7c478bd9Sstevel@tonic-gate } 1363*7c478bd9Sstevel@tonic-gate 1364*7c478bd9Sstevel@tonic-gate /* ========== process_archive ============================================= */ 1365*7c478bd9Sstevel@tonic-gate /* 1366*7c478bd9Sstevel@tonic-gate * DESCRIPTION: 1367*7c478bd9Sstevel@tonic-gate * Processes member files of an archive. This function provides 1368*7c478bd9Sstevel@tonic-gate * a loop through an archive equivalent the processing of each_file 1369*7c478bd9Sstevel@tonic-gate * for individual object file. 1370*7c478bd9Sstevel@tonic-gate */ 1371*7c478bd9Sstevel@tonic-gate /* ======================================================================== */ 1372*7c478bd9Sstevel@tonic-gate 1373*7c478bd9Sstevel@tonic-gate static int 1374*7c478bd9Sstevel@tonic-gate process_archive(obj_list * c) 1375*7c478bd9Sstevel@tonic-gate { 1376*7c478bd9Sstevel@tonic-gate Elf_Arhdr *p_ar; 1377*7c478bd9Sstevel@tonic-gate Elf *arf; 1378*7c478bd9Sstevel@tonic-gate Elf_Cmd cmd = ELF_C_READ; 1379*7c478bd9Sstevel@tonic-gate 1380*7c478bd9Sstevel@tonic-gate while ((arf = elf_begin(c->obj->fd, cmd, c->obj->elf)) != 0) { 1381*7c478bd9Sstevel@tonic-gate p_ar = elf_getarhdr(arf); 1382*7c478bd9Sstevel@tonic-gate if (p_ar == NULL) { 1383*7c478bd9Sstevel@tonic-gate if (sflag) 1384*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 1385*7c478bd9Sstevel@tonic-gate "%s: %s\n", 1386*7c478bd9Sstevel@tonic-gate c->obj->filename, elf_errmsg(-1)); 1387*7c478bd9Sstevel@tonic-gate return (FAIL); 1388*7c478bd9Sstevel@tonic-gate } 1389*7c478bd9Sstevel@tonic-gate if ((int)strncmp(p_ar->ar_name, "/", 1) == 0) { 1390*7c478bd9Sstevel@tonic-gate cmd = elf_next(arf); 1391*7c478bd9Sstevel@tonic-gate (void) elf_end(arf); 1392*7c478bd9Sstevel@tonic-gate continue; 1393*7c478bd9Sstevel@tonic-gate } 1394*7c478bd9Sstevel@tonic-gate if (elf_kind(arf) == ELF_K_ELF) { 1395*7c478bd9Sstevel@tonic-gate process(c, arf, p_ar->ar_name); 1396*7c478bd9Sstevel@tonic-gate } else { 1397*7c478bd9Sstevel@tonic-gate cmd = elf_next(arf); 1398*7c478bd9Sstevel@tonic-gate (void) elf_end(arf); 1399*7c478bd9Sstevel@tonic-gate continue; 1400*7c478bd9Sstevel@tonic-gate } 1401*7c478bd9Sstevel@tonic-gate cmd = elf_next(arf); 1402*7c478bd9Sstevel@tonic-gate (void) elf_end(arf); 1403*7c478bd9Sstevel@tonic-gate } /* end while */ 1404*7c478bd9Sstevel@tonic-gate return (SUCCEED); 1405*7c478bd9Sstevel@tonic-gate } 1406*7c478bd9Sstevel@tonic-gate 1407*7c478bd9Sstevel@tonic-gate /* ========== add_dtneeded ================================================ */ 1408*7c478bd9Sstevel@tonic-gate /* 1409*7c478bd9Sstevel@tonic-gate * DESCRIPTION: 1410*7c478bd9Sstevel@tonic-gate * Inserts a new node into the linked list. It is basically for 1411*7c478bd9Sstevel@tonic-gate * generating a simple linked list of DT_NEEDED entries. 1412*7c478bd9Sstevel@tonic-gate */ 1413*7c478bd9Sstevel@tonic-gate /* ======================================================================== */ 1414*7c478bd9Sstevel@tonic-gate 1415*7c478bd9Sstevel@tonic-gate static dt_list * 1416*7c478bd9Sstevel@tonic-gate add_dtneeded(dt_list * p, 1417*7c478bd9Sstevel@tonic-gate dt_list * node) 1418*7c478bd9Sstevel@tonic-gate { 1419*7c478bd9Sstevel@tonic-gate dt_list *head = p, *tail; 1420*7c478bd9Sstevel@tonic-gate 1421*7c478bd9Sstevel@tonic-gate if (!head) 1422*7c478bd9Sstevel@tonic-gate head = node; 1423*7c478bd9Sstevel@tonic-gate else { 1424*7c478bd9Sstevel@tonic-gate tail = head; 1425*7c478bd9Sstevel@tonic-gate if (strcmp(tail->libname, node->libname) == 0) { 1426*7c478bd9Sstevel@tonic-gate free(node); 1427*7c478bd9Sstevel@tonic-gate return (head); 1428*7c478bd9Sstevel@tonic-gate } 1429*7c478bd9Sstevel@tonic-gate while (tail->next != NULL) { 1430*7c478bd9Sstevel@tonic-gate tail = tail->next; 1431*7c478bd9Sstevel@tonic-gate if (strcmp(tail->libname, node->libname) == 0) { 1432*7c478bd9Sstevel@tonic-gate free(node); 1433*7c478bd9Sstevel@tonic-gate return (head); 1434*7c478bd9Sstevel@tonic-gate } 1435*7c478bd9Sstevel@tonic-gate } 1436*7c478bd9Sstevel@tonic-gate tail->next = node; 1437*7c478bd9Sstevel@tonic-gate } 1438*7c478bd9Sstevel@tonic-gate return (head); 1439*7c478bd9Sstevel@tonic-gate } 1440*7c478bd9Sstevel@tonic-gate 1441*7c478bd9Sstevel@tonic-gate /* ========== find_dtneeded =============================================== */ 1442*7c478bd9Sstevel@tonic-gate /* 1443*7c478bd9Sstevel@tonic-gate * DESCRIPTION: 1444*7c478bd9Sstevel@tonic-gate * Find the DT_NEEDED, DT_FILTER, and DT_AUXILIARY entries, and save 1445*7c478bd9Sstevel@tonic-gate * them to link list. 1446*7c478bd9Sstevel@tonic-gate */ 1447*7c478bd9Sstevel@tonic-gate /* ======================================================================== */ 1448*7c478bd9Sstevel@tonic-gate 1449*7c478bd9Sstevel@tonic-gate static void 1450*7c478bd9Sstevel@tonic-gate find_dtneeded(obj_list * c) 1451*7c478bd9Sstevel@tonic-gate { 1452*7c478bd9Sstevel@tonic-gate #if defined(_LP64) 1453*7c478bd9Sstevel@tonic-gate Elf64_Dyn *dcurrent; /* temp 64 bit dynamic table entry ptr */ 1454*7c478bd9Sstevel@tonic-gate #else 1455*7c478bd9Sstevel@tonic-gate Elf32_Dyn *dcurrent; /* temp 32 bit dynamic table entry ptr */ 1456*7c478bd9Sstevel@tonic-gate #endif 1457*7c478bd9Sstevel@tonic-gate dt_list *tmp_lib; 1458*7c478bd9Sstevel@tonic-gate 1459*7c478bd9Sstevel@tonic-gate dcurrent = c->obj->dynsect; 1460*7c478bd9Sstevel@tonic-gate if (!dcurrent) 1461*7c478bd9Sstevel@tonic-gate return; 1462*7c478bd9Sstevel@tonic-gate 1463*7c478bd9Sstevel@tonic-gate /* 1464*7c478bd9Sstevel@tonic-gate * If there are any DT_NEEDED 1465*7c478bd9Sstevel@tonic-gate * entries, add them to the dt_needed list. 1466*7c478bd9Sstevel@tonic-gate */ 1467*7c478bd9Sstevel@tonic-gate 1468*7c478bd9Sstevel@tonic-gate while (dcurrent->d_tag != DT_NULL) { 1469*7c478bd9Sstevel@tonic-gate if (dcurrent->d_tag == DT_NEEDED) { 1470*7c478bd9Sstevel@tonic-gate tmp_lib = (dt_list *) malloc(sizeof (dt_list)); 1471*7c478bd9Sstevel@tonic-gate tmp_lib->libname = c->obj->dynnames + 1472*7c478bd9Sstevel@tonic-gate dcurrent->d_un.d_val; 1473*7c478bd9Sstevel@tonic-gate tmp_lib->d_tag = dcurrent->d_tag; 1474*7c478bd9Sstevel@tonic-gate tmp_lib->next = NULL; 1475*7c478bd9Sstevel@tonic-gate dt_needed = add_dtneeded(dt_needed, tmp_lib); 1476*7c478bd9Sstevel@tonic-gate } 1477*7c478bd9Sstevel@tonic-gate dcurrent++; 1478*7c478bd9Sstevel@tonic-gate } 1479*7c478bd9Sstevel@tonic-gate } 1480*7c478bd9Sstevel@tonic-gate 1481*7c478bd9Sstevel@tonic-gate /* ========= obj_elfcheck ================================================= */ 1482*7c478bd9Sstevel@tonic-gate /* 1483*7c478bd9Sstevel@tonic-gate * DESCRIPTION: 1484*7c478bd9Sstevel@tonic-gate * It checks the elf header and saves its pointer if succeeds. 1485*7c478bd9Sstevel@tonic-gate * It checks the program header and saves its pointer if succeed. 1486*7c478bd9Sstevel@tonic-gate * It checks the section header table and saves its pointer to 1487*7c478bd9Sstevel@tonic-gate * section header table and section header string table if it 1488*7c478bd9Sstevel@tonic-gate * succeeds. It finds dynsym symbol table and saves its pointer. 1489*7c478bd9Sstevel@tonic-gate * It finds symtab and saves its pointers. 1490*7c478bd9Sstevel@tonic-gate */ 1491*7c478bd9Sstevel@tonic-gate /* ======================================================================== */ 1492*7c478bd9Sstevel@tonic-gate 1493*7c478bd9Sstevel@tonic-gate static int 1494*7c478bd9Sstevel@tonic-gate obj_elfcheck(obj_list * c) 1495*7c478bd9Sstevel@tonic-gate { 1496*7c478bd9Sstevel@tonic-gate /* open the file and ELF descriptor */ 1497*7c478bd9Sstevel@tonic-gate if (obj_init(c) == FAIL) { 1498*7c478bd9Sstevel@tonic-gate obj_finis(c); 1499*7c478bd9Sstevel@tonic-gate return (FAIL); 1500*7c478bd9Sstevel@tonic-gate } 1501*7c478bd9Sstevel@tonic-gate /* if it is an archive library */ 1502*7c478bd9Sstevel@tonic-gate if (elf_kind(c->obj->elf) == ELF_K_AR) { 1503*7c478bd9Sstevel@tonic-gate if (process_archive(c) == SUCCEED) 1504*7c478bd9Sstevel@tonic-gate return (SUCCEED); 1505*7c478bd9Sstevel@tonic-gate else 1506*7c478bd9Sstevel@tonic-gate return (FAIL); 1507*7c478bd9Sstevel@tonic-gate } 1508*7c478bd9Sstevel@tonic-gate /* get the ELF header information */ 1509*7c478bd9Sstevel@tonic-gate if (obj_elf_hdr(c) == FAIL) { 1510*7c478bd9Sstevel@tonic-gate obj_finis(c); 1511*7c478bd9Sstevel@tonic-gate return (FAIL); 1512*7c478bd9Sstevel@tonic-gate } 1513*7c478bd9Sstevel@tonic-gate /* get the program header for dynamic, etc. */ 1514*7c478bd9Sstevel@tonic-gate if (obj_prog_hdr(c) == FAIL) { 1515*7c478bd9Sstevel@tonic-gate obj_finis(c); 1516*7c478bd9Sstevel@tonic-gate return (FAIL); 1517*7c478bd9Sstevel@tonic-gate } 1518*7c478bd9Sstevel@tonic-gate /* find and save pointers to application symbol tables */ 1519*7c478bd9Sstevel@tonic-gate if (find_symtabs(c) == FAIL) { 1520*7c478bd9Sstevel@tonic-gate obj_finis(c); 1521*7c478bd9Sstevel@tonic-gate return (FAIL); 1522*7c478bd9Sstevel@tonic-gate } 1523*7c478bd9Sstevel@tonic-gate /* check the existence of application's symbol tables */ 1524*7c478bd9Sstevel@tonic-gate if (obj_app_symtab(c) == FAIL) { 1525*7c478bd9Sstevel@tonic-gate obj_finis(c); 1526*7c478bd9Sstevel@tonic-gate return (FAIL); 1527*7c478bd9Sstevel@tonic-gate } 1528*7c478bd9Sstevel@tonic-gate /* find and save pointers to the dynamic section */ 1529*7c478bd9Sstevel@tonic-gate if (find_dynamic_sect(c) == FAIL) { 1530*7c478bd9Sstevel@tonic-gate obj_finis(c); 1531*7c478bd9Sstevel@tonic-gate return (FAIL); 1532*7c478bd9Sstevel@tonic-gate } 1533*7c478bd9Sstevel@tonic-gate /* 1534*7c478bd9Sstevel@tonic-gate * find the DT_NEEDED entries and save the name to dt_needed link 1535*7c478bd9Sstevel@tonic-gate * list 1536*7c478bd9Sstevel@tonic-gate */ 1537*7c478bd9Sstevel@tonic-gate (void) find_dtneeded(c); 1538*7c478bd9Sstevel@tonic-gate 1539*7c478bd9Sstevel@tonic-gate return (SUCCEED); 1540*7c478bd9Sstevel@tonic-gate } 1541*7c478bd9Sstevel@tonic-gate 1542*7c478bd9Sstevel@tonic-gate /* ========= analyze_dependency ========================================== */ 1543*7c478bd9Sstevel@tonic-gate /* 1544*7c478bd9Sstevel@tonic-gate * DESCRIPTION: 1545*7c478bd9Sstevel@tonic-gate * Read in an dependency object file and analyze it. 1546*7c478bd9Sstevel@tonic-gate * INPUTS: dep_file - dependency object file name 1547*7c478bd9Sstevel@tonic-gate */ 1548*7c478bd9Sstevel@tonic-gate /* ======================================================================= */ 1549*7c478bd9Sstevel@tonic-gate 1550*7c478bd9Sstevel@tonic-gate static int 1551*7c478bd9Sstevel@tonic-gate analyze_dependency(char *dep_file) 1552*7c478bd9Sstevel@tonic-gate { 1553*7c478bd9Sstevel@tonic-gate obj_list *dep_obj; 1554*7c478bd9Sstevel@tonic-gate 1555*7c478bd9Sstevel@tonic-gate if (!dep_file) 1556*7c478bd9Sstevel@tonic-gate return (SUCCEED); 1557*7c478bd9Sstevel@tonic-gate 1558*7c478bd9Sstevel@tonic-gate dep_obj = (obj_list *) malloc(sizeof (obj_list)); 1559*7c478bd9Sstevel@tonic-gate (void) memset(dep_obj, 0, sizeof (obj_list)); 1560*7c478bd9Sstevel@tonic-gate dep_obj->obj = (obj_com *) malloc(sizeof (obj_com)); 1561*7c478bd9Sstevel@tonic-gate (void) memset(dep_obj->obj, 0, sizeof (obj_com)); 1562*7c478bd9Sstevel@tonic-gate dep_obj->next = NULL; 1563*7c478bd9Sstevel@tonic-gate dep_obj->obj->filename = dep_file; 1564*7c478bd9Sstevel@tonic-gate dep_obj->obj->ename = dep_obj->obj->filename; 1565*7c478bd9Sstevel@tonic-gate 1566*7c478bd9Sstevel@tonic-gate if (obj_elfcheck(dep_obj) == FAIL) 1567*7c478bd9Sstevel@tonic-gate return (FAIL); 1568*7c478bd9Sstevel@tonic-gate 1569*7c478bd9Sstevel@tonic-gate if (dep_obj->obj->dsym_names != NULL) 1570*7c478bd9Sstevel@tonic-gate bind_symbols(dep_obj, 1571*7c478bd9Sstevel@tonic-gate dep_obj->obj->dsym_tab, 1572*7c478bd9Sstevel@tonic-gate dep_obj->obj->dsym_num, 1573*7c478bd9Sstevel@tonic-gate dep_obj->obj->dsym_names); 1574*7c478bd9Sstevel@tonic-gate 1575*7c478bd9Sstevel@tonic-gate if (dep_obj->obj->sym_names != NULL) 1576*7c478bd9Sstevel@tonic-gate bind_symbols(dep_obj, 1577*7c478bd9Sstevel@tonic-gate dep_obj->obj->sym_tab, 1578*7c478bd9Sstevel@tonic-gate dep_obj->obj->sym_num, 1579*7c478bd9Sstevel@tonic-gate dep_obj->obj->sym_names); 1580*7c478bd9Sstevel@tonic-gate return (SUCCEED); 1581*7c478bd9Sstevel@tonic-gate } 1582*7c478bd9Sstevel@tonic-gate 1583*7c478bd9Sstevel@tonic-gate /* ========= analyze_main =============================================== */ 1584*7c478bd9Sstevel@tonic-gate /* 1585*7c478bd9Sstevel@tonic-gate * DESCRIPTION: 1586*7c478bd9Sstevel@tonic-gate * Read in an object file and analyze it. 1587*7c478bd9Sstevel@tonic-gate */ 1588*7c478bd9Sstevel@tonic-gate /* ====================================================================== */ 1589*7c478bd9Sstevel@tonic-gate 1590*7c478bd9Sstevel@tonic-gate static void 1591*7c478bd9Sstevel@tonic-gate analyze_main(obj_list * c) 1592*7c478bd9Sstevel@tonic-gate { 1593*7c478bd9Sstevel@tonic-gate int i; 1594*7c478bd9Sstevel@tonic-gate 1595*7c478bd9Sstevel@tonic-gate if (obj_elfcheck(c) == FAIL) 1596*7c478bd9Sstevel@tonic-gate exit(1); 1597*7c478bd9Sstevel@tonic-gate 1598*7c478bd9Sstevel@tonic-gate aflag = FALSE; 1599*7c478bd9Sstevel@tonic-gate 1600*7c478bd9Sstevel@tonic-gate if (c->obj->sym_names != NULL) 1601*7c478bd9Sstevel@tonic-gate scan_symbols(c, 1602*7c478bd9Sstevel@tonic-gate c->obj->sym_tab, 1603*7c478bd9Sstevel@tonic-gate c->obj->sym_num, 1604*7c478bd9Sstevel@tonic-gate c->obj->sym_names); 1605*7c478bd9Sstevel@tonic-gate else if (c->obj->dsym_names != NULL) 1606*7c478bd9Sstevel@tonic-gate scan_symbols(c, 1607*7c478bd9Sstevel@tonic-gate c->obj->dsym_tab, 1608*7c478bd9Sstevel@tonic-gate c->obj->dsym_num, 1609*7c478bd9Sstevel@tonic-gate c->obj->dsym_names); 1610*7c478bd9Sstevel@tonic-gate 1611*7c478bd9Sstevel@tonic-gate if (c->obj->numfiles == 0) 1612*7c478bd9Sstevel@tonic-gate return; 1613*7c478bd9Sstevel@tonic-gate 1614*7c478bd9Sstevel@tonic-gate for (i = 0; i < c->obj->numfiles; i++) 1615*7c478bd9Sstevel@tonic-gate (void) analyze_dependency(c->obj->filenames[i]); 1616*7c478bd9Sstevel@tonic-gate } 1617*7c478bd9Sstevel@tonic-gate 1618*7c478bd9Sstevel@tonic-gate /* ========= analyze_args ================================================= */ 1619*7c478bd9Sstevel@tonic-gate /* 1620*7c478bd9Sstevel@tonic-gate * DESCRIPTION: 1621*7c478bd9Sstevel@tonic-gate * Analyze the command-line options. 1622*7c478bd9Sstevel@tonic-gate */ 1623*7c478bd9Sstevel@tonic-gate /* ======================================================================== */ 1624*7c478bd9Sstevel@tonic-gate 1625*7c478bd9Sstevel@tonic-gate static int 1626*7c478bd9Sstevel@tonic-gate analyze_args(obj_list * c, 1627*7c478bd9Sstevel@tonic-gate int argc, 1628*7c478bd9Sstevel@tonic-gate char *argv[]) 1629*7c478bd9Sstevel@tonic-gate { 1630*7c478bd9Sstevel@tonic-gate extern char *optarg; 1631*7c478bd9Sstevel@tonic-gate extern int optind; 1632*7c478bd9Sstevel@tonic-gate int option; 1633*7c478bd9Sstevel@tonic-gate int i; 1634*7c478bd9Sstevel@tonic-gate char *nameptr; 1635*7c478bd9Sstevel@tonic-gate char slash = '/'; 1636*7c478bd9Sstevel@tonic-gate int errflg = 0; 1637*7c478bd9Sstevel@tonic-gate 1638*7c478bd9Sstevel@tonic-gate if ((nameptr = strrchr(argv[0], slash)) != NULL) 1639*7c478bd9Sstevel@tonic-gate nameptr++; 1640*7c478bd9Sstevel@tonic-gate else 1641*7c478bd9Sstevel@tonic-gate nameptr = argv[0]; 1642*7c478bd9Sstevel@tonic-gate 1643*7c478bd9Sstevel@tonic-gate while ((option = getopt(argc, argv, "pso:a")) != EOF) { 1644*7c478bd9Sstevel@tonic-gate switch (option) { 1645*7c478bd9Sstevel@tonic-gate case 'p': /* just do profiling; write to stdout */ 1646*7c478bd9Sstevel@tonic-gate pflag = 1; 1647*7c478bd9Sstevel@tonic-gate break; 1648*7c478bd9Sstevel@tonic-gate case 's': /* silent mode to turn off stderr messages */ 1649*7c478bd9Sstevel@tonic-gate sflag = 0; 1650*7c478bd9Sstevel@tonic-gate break; 1651*7c478bd9Sstevel@tonic-gate case 'o': /* redirects the output */ 1652*7c478bd9Sstevel@tonic-gate outputfile = optarg; 1653*7c478bd9Sstevel@tonic-gate oflag = 1; 1654*7c478bd9Sstevel@tonic-gate break; 1655*7c478bd9Sstevel@tonic-gate case 'a': /* processes archive as input */ 1656*7c478bd9Sstevel@tonic-gate aflag = 1; 1657*7c478bd9Sstevel@tonic-gate break; 1658*7c478bd9Sstevel@tonic-gate case '?': 1659*7c478bd9Sstevel@tonic-gate default: 1660*7c478bd9Sstevel@tonic-gate errflg++; 1661*7c478bd9Sstevel@tonic-gate } /* end switch */ 1662*7c478bd9Sstevel@tonic-gate } /* end while */ 1663*7c478bd9Sstevel@tonic-gate 1664*7c478bd9Sstevel@tonic-gate /* exit if there are no files to process */ 1665*7c478bd9Sstevel@tonic-gate if (optind >= argc) 1666*7c478bd9Sstevel@tonic-gate errflg++; 1667*7c478bd9Sstevel@tonic-gate if (errflg) { 1668*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 1669*7c478bd9Sstevel@tonic-gate "usage: %s [-p] [-s] [-o outputfile] ", nameptr); 1670*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 1671*7c478bd9Sstevel@tonic-gate "<archive>|<binary_executable>\n"); 1672*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 1673*7c478bd9Sstevel@tonic-gate "\t\t [<archive>|<dynamic library>...]\n"); 1674*7c478bd9Sstevel@tonic-gate return (FALSE); 1675*7c478bd9Sstevel@tonic-gate } /* end if */ 1676*7c478bd9Sstevel@tonic-gate c->obj->filename = argv[optind++]; 1677*7c478bd9Sstevel@tonic-gate c->obj->ename = c->obj->filename; 1678*7c478bd9Sstevel@tonic-gate 1679*7c478bd9Sstevel@tonic-gate /* compute number of files and save their pointers */ 1680*7c478bd9Sstevel@tonic-gate c->obj->numfiles = argc - optind; 1681*7c478bd9Sstevel@tonic-gate 1682*7c478bd9Sstevel@tonic-gate if (c->obj->numfiles > 0) { 1683*7c478bd9Sstevel@tonic-gate i = 0; 1684*7c478bd9Sstevel@tonic-gate c->obj->filenames = (char **) 1685*7c478bd9Sstevel@tonic-gate malloc(sizeof (char *) * 1686*7c478bd9Sstevel@tonic-gate (c->obj->numfiles + 1)); 1687*7c478bd9Sstevel@tonic-gate for (; optind < argc; i++, optind++) 1688*7c478bd9Sstevel@tonic-gate c->obj->filenames[i] = argv[optind]; 1689*7c478bd9Sstevel@tonic-gate } 1690*7c478bd9Sstevel@tonic-gate return (TRUE); 1691*7c478bd9Sstevel@tonic-gate } 1692*7c478bd9Sstevel@tonic-gate 1693*7c478bd9Sstevel@tonic-gate /* ======================================================================= */ 1694*7c478bd9Sstevel@tonic-gate /* 1695*7c478bd9Sstevel@tonic-gate * Here starts the main () 1696*7c478bd9Sstevel@tonic-gate */ 1697*7c478bd9Sstevel@tonic-gate /* ======================================================================= */ 1698*7c478bd9Sstevel@tonic-gate 1699*7c478bd9Sstevel@tonic-gate void 1700*7c478bd9Sstevel@tonic-gate main(int argc, 1701*7c478bd9Sstevel@tonic-gate char **argv) 1702*7c478bd9Sstevel@tonic-gate { 1703*7c478bd9Sstevel@tonic-gate obj_list *main_obj; 1704*7c478bd9Sstevel@tonic-gate dt_list *q; 1705*7c478bd9Sstevel@tonic-gate 1706*7c478bd9Sstevel@tonic-gate main_obj = (obj_list *) malloc(sizeof (obj_list)); 1707*7c478bd9Sstevel@tonic-gate (void) memset(main_obj, 0, sizeof (obj_list)); 1708*7c478bd9Sstevel@tonic-gate main_obj->obj = (obj_com *) malloc(sizeof (obj_com)); 1709*7c478bd9Sstevel@tonic-gate (void) memset(main_obj->obj, 0, sizeof (obj_com)); 1710*7c478bd9Sstevel@tonic-gate main_obj->next = NULL; 1711*7c478bd9Sstevel@tonic-gate 1712*7c478bd9Sstevel@tonic-gate if (!analyze_args(main_obj, argc, argv)) 1713*7c478bd9Sstevel@tonic-gate exit(1); 1714*7c478bd9Sstevel@tonic-gate 1715*7c478bd9Sstevel@tonic-gate if (oflag && pflag) { 1716*7c478bd9Sstevel@tonic-gate if ((OUTPUT_FD = fopen(outputfile, "w")) == NULL) { 1717*7c478bd9Sstevel@tonic-gate if (sflag) 1718*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 1719*7c478bd9Sstevel@tonic-gate "\nfopen failed to open <%s>...\n\n", 1720*7c478bd9Sstevel@tonic-gate outputfile); 1721*7c478bd9Sstevel@tonic-gate exit(1); 1722*7c478bd9Sstevel@tonic-gate } 1723*7c478bd9Sstevel@tonic-gate } 1724*7c478bd9Sstevel@tonic-gate /* generates profile report if pflag is set */ 1725*7c478bd9Sstevel@tonic-gate if (pflag) 1726*7c478bd9Sstevel@tonic-gate (void) fprintf(OUTPUT_FD, 1727*7c478bd9Sstevel@tonic-gate "#generated by %s\n", 1728*7c478bd9Sstevel@tonic-gate argv[0]); 1729*7c478bd9Sstevel@tonic-gate 1730*7c478bd9Sstevel@tonic-gate /* analyze the input file */ 1731*7c478bd9Sstevel@tonic-gate analyze_main(main_obj); 1732*7c478bd9Sstevel@tonic-gate 1733*7c478bd9Sstevel@tonic-gate /* generates profile report */ 1734*7c478bd9Sstevel@tonic-gate if (!pflag) 1735*7c478bd9Sstevel@tonic-gate output_binding(argv[0], main_obj->obj->ename); 1736*7c478bd9Sstevel@tonic-gate 1737*7c478bd9Sstevel@tonic-gate /* close the library .so file descriptor and ELF descriptor */ 1738*7c478bd9Sstevel@tonic-gate obj_finis(main_obj); 1739*7c478bd9Sstevel@tonic-gate 1740*7c478bd9Sstevel@tonic-gate /* de-allocates the dt_needed link list */ 1741*7c478bd9Sstevel@tonic-gate if (dt_needed) { 1742*7c478bd9Sstevel@tonic-gate while (dt_needed) { 1743*7c478bd9Sstevel@tonic-gate q = dt_needed; 1744*7c478bd9Sstevel@tonic-gate dt_needed = dt_needed->next; 1745*7c478bd9Sstevel@tonic-gate free(q); 1746*7c478bd9Sstevel@tonic-gate } 1747*7c478bd9Sstevel@tonic-gate } 1748*7c478bd9Sstevel@tonic-gate /* close the output redirect file descriptor */ 1749*7c478bd9Sstevel@tonic-gate if (oflag) 1750*7c478bd9Sstevel@tonic-gate (void) fclose(OUTPUT_FD); 1751*7c478bd9Sstevel@tonic-gate 1752*7c478bd9Sstevel@tonic-gate exit(0); 1753*7c478bd9Sstevel@tonic-gate } 1754