17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 57a5d89c4Sab196087 * Common Development and Distribution License (the "License"). 67a5d89c4Sab196087 * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate /* 22*20c1c355SRod Evans * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. 237c478bd9Sstevel@tonic-gate */ 247c478bd9Sstevel@tonic-gate 257c478bd9Sstevel@tonic-gate /* 267c478bd9Sstevel@tonic-gate * dispsyms: Display Symbols 277c478bd9Sstevel@tonic-gate * 287c478bd9Sstevel@tonic-gate * This program demonstrates the use of the libelf interface to 297c478bd9Sstevel@tonic-gate * read an ELF file. dispsyms will open an ELF file using 307c478bd9Sstevel@tonic-gate * elf_begin(ELF_C_READ) and examine search the ELF file 317a5d89c4Sab196087 * for a symbol table (SHT_SYMTAB, SHT_DYNSYM, or SHT_SUNW_LDYNSYM). 327a5d89c4Sab196087 * It will display the contents of any symbol tables it finds. 337c478bd9Sstevel@tonic-gate * 347c478bd9Sstevel@tonic-gate * Note: This program also understands about the use 357c478bd9Sstevel@tonic-gate * of 'Extended ELF Section indexes' and will 367c478bd9Sstevel@tonic-gate * decode a corresponding SHT_SYMTAB_SHNDX 377c478bd9Sstevel@tonic-gate * section if required. 387c478bd9Sstevel@tonic-gate */ 397c478bd9Sstevel@tonic-gate #include <stdio.h> 407c478bd9Sstevel@tonic-gate #include <libelf.h> 417c478bd9Sstevel@tonic-gate #include <gelf.h> 427c478bd9Sstevel@tonic-gate #include <fcntl.h> 437c478bd9Sstevel@tonic-gate #include <unistd.h> 447c478bd9Sstevel@tonic-gate #include <stdlib.h> 457c478bd9Sstevel@tonic-gate #include <string.h> 467c478bd9Sstevel@tonic-gate 477c478bd9Sstevel@tonic-gate static const char *symbind[STB_NUM] = { 487c478bd9Sstevel@tonic-gate /* STB_LOCL */ "LOCL", 497c478bd9Sstevel@tonic-gate /* STB_GLOBAL */ "GLOB", 507c478bd9Sstevel@tonic-gate /* STB_WEAK */ "WEAK" 517c478bd9Sstevel@tonic-gate }; 527c478bd9Sstevel@tonic-gate 537c478bd9Sstevel@tonic-gate static const char *symtype[STT_NUM] = { 547c478bd9Sstevel@tonic-gate /* STT_NOTYPE */ "NOTY", 557c478bd9Sstevel@tonic-gate /* STT_OBJECT */ "OBJT", 567c478bd9Sstevel@tonic-gate /* STT_FUNC */ "FUNC", 577c478bd9Sstevel@tonic-gate /* STT_SECTION */ "SECT", 587c478bd9Sstevel@tonic-gate /* STT_FILE */ "FILE", 597c478bd9Sstevel@tonic-gate /* STT_COMMON */ "COMM", 607c478bd9Sstevel@tonic-gate /* STT_TLS */ "TLS" 617c478bd9Sstevel@tonic-gate }; 6262b628a6SAli Bahrami #if STT_NUM != (STT_TLS + 1) 637e16fca0SAli Bahrami #error "STT_NUM has grown. Update symtype[]." 647e16fca0SAli Bahrami #endif 657c478bd9Sstevel@tonic-gate 667c478bd9Sstevel@tonic-gate #define INTSTRLEN 32 677c478bd9Sstevel@tonic-gate 687c478bd9Sstevel@tonic-gate 697c478bd9Sstevel@tonic-gate static void 707c478bd9Sstevel@tonic-gate print_symtab(Elf *elf, const char *file) 717c478bd9Sstevel@tonic-gate { 72*20c1c355SRod Evans Elf_Scn *scn = NULL; 737c478bd9Sstevel@tonic-gate GElf_Shdr shdr; 747c478bd9Sstevel@tonic-gate GElf_Ehdr ehdr; 757c478bd9Sstevel@tonic-gate size_t shstrndx; 767c478bd9Sstevel@tonic-gate 777c478bd9Sstevel@tonic-gate 78*20c1c355SRod Evans if (gelf_getehdr(elf, &ehdr) == NULL) { 797c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "%s: elf_getehdr() failed: %s\n", 807c478bd9Sstevel@tonic-gate file, elf_errmsg(0)); 817c478bd9Sstevel@tonic-gate return; 827c478bd9Sstevel@tonic-gate } 837c478bd9Sstevel@tonic-gate 8462b628a6SAli Bahrami if (elf_getshdrstrndx(elf, &shstrndx) == -1) { 8562b628a6SAli Bahrami (void) fprintf(stderr, "%s: elf_getshdrstrndx() failed: %s\n", 867c478bd9Sstevel@tonic-gate file, elf_errmsg(0)); 877c478bd9Sstevel@tonic-gate return; 887c478bd9Sstevel@tonic-gate } 897c478bd9Sstevel@tonic-gate 90*20c1c355SRod Evans while ((scn = elf_nextscn(elf, scn)) != NULL) { 91*20c1c355SRod Evans uint_t symcnt, ndx, nosymshndx; 92*20c1c355SRod Evans Elf_Data *symdata, *shndxdata; 937c478bd9Sstevel@tonic-gate 94*20c1c355SRod Evans if (gelf_getshdr(scn, &shdr) == NULL) { 957c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 967c478bd9Sstevel@tonic-gate "%s: elf_getshdr() failed: %s\n", 977c478bd9Sstevel@tonic-gate file, elf_errmsg(0)); 987c478bd9Sstevel@tonic-gate return; 997c478bd9Sstevel@tonic-gate } 1007c478bd9Sstevel@tonic-gate if ((shdr.sh_type != SHT_SYMTAB) && 1017a5d89c4Sab196087 (shdr.sh_type != SHT_DYNSYM) && 1027a5d89c4Sab196087 (shdr.sh_type != SHT_SUNW_LDYNSYM)) 1037c478bd9Sstevel@tonic-gate continue; 1047c478bd9Sstevel@tonic-gate 1057c478bd9Sstevel@tonic-gate /* 1067c478bd9Sstevel@tonic-gate * Get the data associated with the Symbol 1077c478bd9Sstevel@tonic-gate * section. 1087c478bd9Sstevel@tonic-gate */ 109*20c1c355SRod Evans if ((symdata = elf_getdata(scn, NULL)) == NULL) { 1107c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 1117c478bd9Sstevel@tonic-gate "%s: elf_getdata() failed: %s\n", 1127c478bd9Sstevel@tonic-gate file, elf_errmsg(0)); 1137c478bd9Sstevel@tonic-gate return; 1147c478bd9Sstevel@tonic-gate } 1157c478bd9Sstevel@tonic-gate 1167c478bd9Sstevel@tonic-gate /* 1177c478bd9Sstevel@tonic-gate * Print symbol table title and header for symbol display 1187c478bd9Sstevel@tonic-gate */ 1197c478bd9Sstevel@tonic-gate (void) printf("\nSymTab: %s:%s\n", file, 1207c478bd9Sstevel@tonic-gate elf_strptr(elf, shstrndx, shdr.sh_name)); 1217c478bd9Sstevel@tonic-gate (void) printf(" index value size type " 1227c478bd9Sstevel@tonic-gate "bind oth shndx name\n"); 1237c478bd9Sstevel@tonic-gate 1247c478bd9Sstevel@tonic-gate /* 1257c478bd9Sstevel@tonic-gate * We now iterate over the full symbol table printing 1267c478bd9Sstevel@tonic-gate * the symbols as we go. 1277c478bd9Sstevel@tonic-gate */ 1287c478bd9Sstevel@tonic-gate shndxdata = 0; 1297c478bd9Sstevel@tonic-gate nosymshndx = 0; 1307c478bd9Sstevel@tonic-gate symcnt = shdr.sh_size / shdr.sh_entsize; 1317c478bd9Sstevel@tonic-gate for (ndx = 0; ndx < symcnt; ndx++) { 1327c478bd9Sstevel@tonic-gate GElf_Sym sym; 1337c478bd9Sstevel@tonic-gate Elf32_Word shndx; 134*20c1c355SRod Evans uint_t type, bind, specshndx; 1357c478bd9Sstevel@tonic-gate char bindbuf[INTSTRLEN]; 1367c478bd9Sstevel@tonic-gate char typebuf[INTSTRLEN]; 1377c478bd9Sstevel@tonic-gate char shndxbuf[INTSTRLEN]; 138*20c1c355SRod Evans const char *bindstr, *typestr, *shndxstr; 1397c478bd9Sstevel@tonic-gate 1407c478bd9Sstevel@tonic-gate /* 1417c478bd9Sstevel@tonic-gate * Get a symbol entry 1427c478bd9Sstevel@tonic-gate */ 1437c478bd9Sstevel@tonic-gate if (gelf_getsymshndx(symdata, shndxdata, ndx, 1447c478bd9Sstevel@tonic-gate &sym, &shndx) == NULL) { 1457c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 1467c478bd9Sstevel@tonic-gate "%s: gelf_getsymshndx() failed: %s\n", 1477c478bd9Sstevel@tonic-gate file, elf_errmsg(0)); 1487c478bd9Sstevel@tonic-gate return; 1497c478bd9Sstevel@tonic-gate } 1507c478bd9Sstevel@tonic-gate /* 151*20c1c355SRod Evans * Check to see if this symbol's st_shndx is using 152*20c1c355SRod Evans * the 'Extended SHNDX table' for a SYMTAB. 1537c478bd9Sstevel@tonic-gate * 154*20c1c355SRod Evans * If it is - and we haven't searched before, go 155*20c1c355SRod Evans * find the associated SHT_SYMTAB_SHNDX section. 1567c478bd9Sstevel@tonic-gate */ 1577c478bd9Sstevel@tonic-gate if ((sym.st_shndx == SHN_XINDEX) && 1587c478bd9Sstevel@tonic-gate (shndxdata == 0) && (nosymshndx == 0)) { 159*20c1c355SRod Evans Elf_Scn *_scn = NULL; 1607c478bd9Sstevel@tonic-gate GElf_Shdr _shdr; 1617c478bd9Sstevel@tonic-gate GElf_Word symscnndx; 162*20c1c355SRod Evans 1637c478bd9Sstevel@tonic-gate specshndx = 0; 1647c478bd9Sstevel@tonic-gate symscnndx = elf_ndxscn(scn); 1657c478bd9Sstevel@tonic-gate 166*20c1c355SRod Evans while ((_scn = 167*20c1c355SRod Evans elf_nextscn(elf, _scn)) != NULL) { 168*20c1c355SRod Evans if (gelf_getshdr(_scn, &_shdr) == NULL) 1697c478bd9Sstevel@tonic-gate break; 170*20c1c355SRod Evans 1717c478bd9Sstevel@tonic-gate /* 1727c478bd9Sstevel@tonic-gate * We've found the Symtab SHNDX table 1737c478bd9Sstevel@tonic-gate * if it's of type SHT_SYMTAB_SHNDX 1747c478bd9Sstevel@tonic-gate * and it's shdr.sh_link points to the 1757c478bd9Sstevel@tonic-gate * section index for the current symbol 1767c478bd9Sstevel@tonic-gate * table. 1777c478bd9Sstevel@tonic-gate */ 1787c478bd9Sstevel@tonic-gate if ((_shdr.sh_type == 1797c478bd9Sstevel@tonic-gate SHT_SYMTAB_SHNDX) && 180*20c1c355SRod Evans (_shdr.sh_link == symscnndx) && 181*20c1c355SRod Evans ((shndxdata = elf_getdata(_scn, 182*20c1c355SRod Evans NULL)) != NULL)) 1837c478bd9Sstevel@tonic-gate break; 1847c478bd9Sstevel@tonic-gate } 1857c478bd9Sstevel@tonic-gate /* 1867c478bd9Sstevel@tonic-gate * Get a symbol entry 1877c478bd9Sstevel@tonic-gate */ 1887c478bd9Sstevel@tonic-gate if (shndxdata && 1897c478bd9Sstevel@tonic-gate (gelf_getsymshndx(symdata, shndxdata, ndx, 1907c478bd9Sstevel@tonic-gate &sym, &shndx) == NULL)) { 1917c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 1927c478bd9Sstevel@tonic-gate "%s: gelf_getsymshndx() " 1937c478bd9Sstevel@tonic-gate "failed: %s\n", 1947c478bd9Sstevel@tonic-gate file, elf_errmsg(0)); 1957c478bd9Sstevel@tonic-gate return; 1967c478bd9Sstevel@tonic-gate } 1977c478bd9Sstevel@tonic-gate /* 1987c478bd9Sstevel@tonic-gate * No Symtab SHNDX table was found. We could 1997c478bd9Sstevel@tonic-gate * give a fatal error here - instead we'll 2007c478bd9Sstevel@tonic-gate * just mark that fact and display as much of 2017c478bd9Sstevel@tonic-gate * the symbol table as we can. Any symbol 2027c478bd9Sstevel@tonic-gate * displayed with a XINDX section index has 2037c478bd9Sstevel@tonic-gate * a bogus value. 2047c478bd9Sstevel@tonic-gate */ 2057c478bd9Sstevel@tonic-gate if (shndxdata == 0) 2067c478bd9Sstevel@tonic-gate nosymshndx = 1; 2077c478bd9Sstevel@tonic-gate } 2087c478bd9Sstevel@tonic-gate 2097c478bd9Sstevel@tonic-gate /* 2107c478bd9Sstevel@tonic-gate * Decode the type & binding information 2117c478bd9Sstevel@tonic-gate */ 2127c478bd9Sstevel@tonic-gate type = GELF_ST_TYPE(sym.st_info); 2137c478bd9Sstevel@tonic-gate bind = GELF_ST_BIND(sym.st_info); 2147c478bd9Sstevel@tonic-gate 2157c478bd9Sstevel@tonic-gate if (type < STT_NUM) 2167c478bd9Sstevel@tonic-gate typestr = symtype[type]; 2177c478bd9Sstevel@tonic-gate else { 2187c478bd9Sstevel@tonic-gate (void) snprintf(typebuf, INTSTRLEN, 2197c478bd9Sstevel@tonic-gate "%d", type); 2207c478bd9Sstevel@tonic-gate typestr = typebuf; 2217c478bd9Sstevel@tonic-gate } 2227c478bd9Sstevel@tonic-gate 2237c478bd9Sstevel@tonic-gate if (bind < STB_NUM) 2247c478bd9Sstevel@tonic-gate bindstr = symbind[bind]; 2257c478bd9Sstevel@tonic-gate else { 2267c478bd9Sstevel@tonic-gate (void) snprintf(bindbuf, INTSTRLEN, 2277c478bd9Sstevel@tonic-gate "%d", bind); 2287c478bd9Sstevel@tonic-gate bindstr = bindbuf; 2297c478bd9Sstevel@tonic-gate } 2307c478bd9Sstevel@tonic-gate 2317c478bd9Sstevel@tonic-gate 2327c478bd9Sstevel@tonic-gate specshndx = 0; 2337c478bd9Sstevel@tonic-gate if (sym.st_shndx < SHN_LORESERVE) 2347c478bd9Sstevel@tonic-gate shndx = sym.st_shndx; 2357c478bd9Sstevel@tonic-gate else if ((sym.st_shndx != SHN_XINDEX) || 2367c478bd9Sstevel@tonic-gate (shndxdata == NULL)) { 2377c478bd9Sstevel@tonic-gate shndx = sym.st_shndx; 2387c478bd9Sstevel@tonic-gate specshndx = 1; 2397c478bd9Sstevel@tonic-gate } 2407c478bd9Sstevel@tonic-gate 2417c478bd9Sstevel@tonic-gate if (shndx == SHN_UNDEF) { 2427c478bd9Sstevel@tonic-gate shndxstr = (const char *)"UNDEF"; 2437c478bd9Sstevel@tonic-gate 2447c478bd9Sstevel@tonic-gate } else if (specshndx) { 2457c478bd9Sstevel@tonic-gate if (shndx == SHN_ABS) 2467c478bd9Sstevel@tonic-gate shndxstr = (const char *)"ABS"; 2477c478bd9Sstevel@tonic-gate else if (shndx == SHN_COMMON) 2487c478bd9Sstevel@tonic-gate shndxstr = (const char *)"COMM"; 2497c478bd9Sstevel@tonic-gate else if (shndx == SHN_XINDEX) 2507c478bd9Sstevel@tonic-gate shndxstr = (const char *)"XIND"; 2517c478bd9Sstevel@tonic-gate else { 2527c478bd9Sstevel@tonic-gate (void) snprintf(shndxbuf, INTSTRLEN, 2537c478bd9Sstevel@tonic-gate "%ld", shndx); 2547c478bd9Sstevel@tonic-gate shndxstr = shndxbuf; 2557c478bd9Sstevel@tonic-gate } 2567c478bd9Sstevel@tonic-gate } else { 2577c478bd9Sstevel@tonic-gate (void) snprintf(shndxbuf, INTSTRLEN, 2587c478bd9Sstevel@tonic-gate "%ld", shndx); 2597c478bd9Sstevel@tonic-gate shndxstr = shndxbuf; 2607c478bd9Sstevel@tonic-gate } 2617c478bd9Sstevel@tonic-gate 2627c478bd9Sstevel@tonic-gate /* 2637c478bd9Sstevel@tonic-gate * Display the symbol entry. 2647c478bd9Sstevel@tonic-gate */ 2657c478bd9Sstevel@tonic-gate (void) printf("[%3d] 0x%08llx 0x%08llx %-4s " 2667c478bd9Sstevel@tonic-gate "%-6s %2d %5s %s\n", 2677c478bd9Sstevel@tonic-gate ndx, sym.st_value, sym.st_size, 2687c478bd9Sstevel@tonic-gate typestr, bindstr, sym.st_other, shndxstr, 2697c478bd9Sstevel@tonic-gate elf_strptr(elf, shdr.sh_link, sym.st_name)); 2707c478bd9Sstevel@tonic-gate } 2717c478bd9Sstevel@tonic-gate } 2727c478bd9Sstevel@tonic-gate } 2737c478bd9Sstevel@tonic-gate 2747c478bd9Sstevel@tonic-gate 2757c478bd9Sstevel@tonic-gate static void 2767c478bd9Sstevel@tonic-gate process_elf(Elf *elf, char *file, int fd, int member) 2777c478bd9Sstevel@tonic-gate { 2787c478bd9Sstevel@tonic-gate Elf_Cmd cmd; 2797c478bd9Sstevel@tonic-gate Elf *_elf; 2807c478bd9Sstevel@tonic-gate 2817c478bd9Sstevel@tonic-gate switch (elf_kind(elf)) { 2827c478bd9Sstevel@tonic-gate case ELF_K_ELF: 2837c478bd9Sstevel@tonic-gate /* 2847c478bd9Sstevel@tonic-gate * This is an ELF file, now attempt to find it's 2857c478bd9Sstevel@tonic-gate * .comment section and to display it. 2867c478bd9Sstevel@tonic-gate */ 2877c478bd9Sstevel@tonic-gate print_symtab(elf, file); 2887c478bd9Sstevel@tonic-gate break; 2897c478bd9Sstevel@tonic-gate case ELF_K_AR: 2907c478bd9Sstevel@tonic-gate /* 2917c478bd9Sstevel@tonic-gate * Archives contain multiple ELF files, which can each 2927c478bd9Sstevel@tonic-gate * in turn be examined with libelf. 2937c478bd9Sstevel@tonic-gate * 2947c478bd9Sstevel@tonic-gate * The below loop will iterate over each member of the 295*20c1c355SRod Evans * archive and recursively call process_elf(). 2967c478bd9Sstevel@tonic-gate */ 2977c478bd9Sstevel@tonic-gate cmd = ELF_C_READ; 298*20c1c355SRod Evans while ((_elf = elf_begin(fd, cmd, elf)) != NULL) { 2997c478bd9Sstevel@tonic-gate Elf_Arhdr *arhdr; 3007c478bd9Sstevel@tonic-gate char buffer[1024]; 3017c478bd9Sstevel@tonic-gate 3027c478bd9Sstevel@tonic-gate arhdr = elf_getarhdr(_elf); 3037c478bd9Sstevel@tonic-gate 3047c478bd9Sstevel@tonic-gate /* 3057c478bd9Sstevel@tonic-gate * Build up file names based off of 3067c478bd9Sstevel@tonic-gate * 'archivename(membername)'. 3077c478bd9Sstevel@tonic-gate */ 3087c478bd9Sstevel@tonic-gate (void) snprintf(buffer, 1024, "%s(%s)", 3097c478bd9Sstevel@tonic-gate file, arhdr->ar_name); 3107c478bd9Sstevel@tonic-gate 3117c478bd9Sstevel@tonic-gate /* 312*20c1c355SRod Evans * Recursively process the ELF members. 3137c478bd9Sstevel@tonic-gate */ 3147c478bd9Sstevel@tonic-gate process_elf(_elf, buffer, fd, 1); 3157c478bd9Sstevel@tonic-gate cmd = elf_next(_elf); 3167c478bd9Sstevel@tonic-gate (void) elf_end(_elf); 3177c478bd9Sstevel@tonic-gate } 3187c478bd9Sstevel@tonic-gate break; 3197c478bd9Sstevel@tonic-gate default: 3207c478bd9Sstevel@tonic-gate if (!member) 3217c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 3227c478bd9Sstevel@tonic-gate "%s: unexpected elf_kind(): 0x%x\n", 3237c478bd9Sstevel@tonic-gate file, elf_kind(elf)); 3247c478bd9Sstevel@tonic-gate return; 3257c478bd9Sstevel@tonic-gate } 3267c478bd9Sstevel@tonic-gate } 3277c478bd9Sstevel@tonic-gate 3287c478bd9Sstevel@tonic-gate int 3297c478bd9Sstevel@tonic-gate main(int argc, char **argv) 3307c478bd9Sstevel@tonic-gate { 3317c478bd9Sstevel@tonic-gate int i; 3327c478bd9Sstevel@tonic-gate 3337c478bd9Sstevel@tonic-gate if (argc < 2) { 3347c478bd9Sstevel@tonic-gate (void) printf("usage: %s elf_file ...\n", argv[0]); 3357c478bd9Sstevel@tonic-gate return (1); 3367c478bd9Sstevel@tonic-gate } 3377c478bd9Sstevel@tonic-gate 3387c478bd9Sstevel@tonic-gate /* 3397c478bd9Sstevel@tonic-gate * Initialize the elf library, must be called before elf_begin() 3407c478bd9Sstevel@tonic-gate * can be called. 3417c478bd9Sstevel@tonic-gate */ 3427c478bd9Sstevel@tonic-gate if (elf_version(EV_CURRENT) == EV_NONE) { 3437c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 3447c478bd9Sstevel@tonic-gate "elf_version() failed: %s\n", elf_errmsg(0)); 3457c478bd9Sstevel@tonic-gate return (1); 3467c478bd9Sstevel@tonic-gate } 3477c478bd9Sstevel@tonic-gate 3487c478bd9Sstevel@tonic-gate for (i = 1; i < argc; i++) { 3497c478bd9Sstevel@tonic-gate int fd; 3507c478bd9Sstevel@tonic-gate Elf *elf; 3517c478bd9Sstevel@tonic-gate char *elf_fname; 3527c478bd9Sstevel@tonic-gate 3537c478bd9Sstevel@tonic-gate elf_fname = argv[i]; 3547c478bd9Sstevel@tonic-gate if ((fd = open(elf_fname, O_RDONLY)) == -1) { 3557c478bd9Sstevel@tonic-gate perror("open"); 3567c478bd9Sstevel@tonic-gate continue; 3577c478bd9Sstevel@tonic-gate } 3587c478bd9Sstevel@tonic-gate 3597c478bd9Sstevel@tonic-gate /* 3607c478bd9Sstevel@tonic-gate * Attempt to open an Elf descriptor Read-Only 3617c478bd9Sstevel@tonic-gate * for each file. 3627c478bd9Sstevel@tonic-gate */ 3637c478bd9Sstevel@tonic-gate if ((elf = elf_begin(fd, ELF_C_READ, 0)) == NULL) { 3647c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "elf_begin() failed: %s\n", 3657c478bd9Sstevel@tonic-gate elf_errmsg(0)); 3667c478bd9Sstevel@tonic-gate (void) close(fd); 3677c478bd9Sstevel@tonic-gate continue; 3687c478bd9Sstevel@tonic-gate } 3697c478bd9Sstevel@tonic-gate 3707c478bd9Sstevel@tonic-gate /* 3717c478bd9Sstevel@tonic-gate * Process each elf descriptor. 3727c478bd9Sstevel@tonic-gate */ 3737c478bd9Sstevel@tonic-gate process_elf(elf, elf_fname, fd, 0); 3747c478bd9Sstevel@tonic-gate (void) elf_end(elf); 3757c478bd9Sstevel@tonic-gate (void) close(fd); 3767c478bd9Sstevel@tonic-gate } 3777c478bd9Sstevel@tonic-gate 3787c478bd9Sstevel@tonic-gate return (0); 3797c478bd9Sstevel@tonic-gate } 380