10Sstevel@tonic-gate /* 20Sstevel@tonic-gate * CDDL HEADER START 30Sstevel@tonic-gate * 40Sstevel@tonic-gate * The contents of this file are subject to the terms of the 50Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 60Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 70Sstevel@tonic-gate * with the License. 80Sstevel@tonic-gate * 90Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 100Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 110Sstevel@tonic-gate * See the License for the specific language governing permissions 120Sstevel@tonic-gate * and limitations under the License. 130Sstevel@tonic-gate * 140Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 150Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 160Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 170Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 180Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 190Sstevel@tonic-gate * 200Sstevel@tonic-gate * CDDL HEADER END 210Sstevel@tonic-gate */ 220Sstevel@tonic-gate /* 230Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 240Sstevel@tonic-gate * Use is subject to license terms. 250Sstevel@tonic-gate */ 260Sstevel@tonic-gate 270Sstevel@tonic-gate /* 280Sstevel@tonic-gate * Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T 290Sstevel@tonic-gate * All Rights Reserved 300Sstevel@tonic-gate */ 310Sstevel@tonic-gate 320Sstevel@tonic-gate /* 330Sstevel@tonic-gate * Copyright (c) 1987, 1988 Microsoft Corporation 340Sstevel@tonic-gate * All Rights Reserved 350Sstevel@tonic-gate */ 360Sstevel@tonic-gate 370Sstevel@tonic-gate /* 380Sstevel@tonic-gate * Copyright (c) 1979 Regents of the University of California 390Sstevel@tonic-gate */ 400Sstevel@tonic-gate 410Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 420Sstevel@tonic-gate 430Sstevel@tonic-gate #include <stdio.h> 440Sstevel@tonic-gate #include "a.out.h" 450Sstevel@tonic-gate #include <ctype.h> 460Sstevel@tonic-gate #include <wchar.h> 470Sstevel@tonic-gate #include <wctype.h> 480Sstevel@tonic-gate #include <libelf.h> 490Sstevel@tonic-gate #include <sys/elf.h> 500Sstevel@tonic-gate #include <locale.h> 510Sstevel@tonic-gate #include <string.h> 520Sstevel@tonic-gate #include <stdlib.h> 530Sstevel@tonic-gate #include <sys/types.h> 540Sstevel@tonic-gate #include <unistd.h> 550Sstevel@tonic-gate #include <limits.h> 560Sstevel@tonic-gate #include <widec.h> 570Sstevel@tonic-gate #include <gelf.h> 580Sstevel@tonic-gate #include <errno.h> 590Sstevel@tonic-gate 600Sstevel@tonic-gate 610Sstevel@tonic-gate #define NOTOUT 0 620Sstevel@tonic-gate #define AOUT 1 630Sstevel@tonic-gate #define ELF 4 640Sstevel@tonic-gate 650Sstevel@tonic-gate struct aexec ahdr; 660Sstevel@tonic-gate 670Sstevel@tonic-gate /* 680Sstevel@tonic-gate * function prototypes 690Sstevel@tonic-gate */ 700Sstevel@tonic-gate static void Usage(); 710Sstevel@tonic-gate static void find(long); 720Sstevel@tonic-gate static int ismagic(int, struct aexec *, FILE *); 730Sstevel@tonic-gate static int tryelf(FILE *); 740Sstevel@tonic-gate static int dirt(int, int); 750Sstevel@tonic-gate 760Sstevel@tonic-gate 770Sstevel@tonic-gate /* 780Sstevel@tonic-gate * Strings - extract strings from an object file for whatever 790Sstevel@tonic-gate * 800Sstevel@tonic-gate * The algorithm is to look for sequences of "non-junk" characters 810Sstevel@tonic-gate * The variable "minlen" is the minimum length string printed. 820Sstevel@tonic-gate * This helps get rid of garbage. 830Sstevel@tonic-gate * Default minimum string length is 4 characters. 840Sstevel@tonic-gate * 850Sstevel@tonic-gate */ 860Sstevel@tonic-gate 870Sstevel@tonic-gate #define DEF_MIN_STRING 4 880Sstevel@tonic-gate 890Sstevel@tonic-gate static int tflg; 900Sstevel@tonic-gate static char t_format; 910Sstevel@tonic-gate static int aflg; 920Sstevel@tonic-gate static int minlength = 0; 930Sstevel@tonic-gate static int isClocale = 0; 940Sstevel@tonic-gate static char *buf = NULL; 950Sstevel@tonic-gate static char *tbuf = NULL; 960Sstevel@tonic-gate static size_t buf_size = 0; 970Sstevel@tonic-gate static int rc = 0; /* exit code */ 980Sstevel@tonic-gate 99*213Smuffin int 1000Sstevel@tonic-gate main(argc, argv) 1010Sstevel@tonic-gate int argc; 1020Sstevel@tonic-gate char *argv[]; 1030Sstevel@tonic-gate { 1040Sstevel@tonic-gate int hsize; 1050Sstevel@tonic-gate int htype; 1060Sstevel@tonic-gate int fd; 1070Sstevel@tonic-gate Elf *elf; 1080Sstevel@tonic-gate GElf_Ehdr ehdr; 1090Sstevel@tonic-gate Elf_Scn *scn; 1100Sstevel@tonic-gate GElf_Shdr shdr; 1110Sstevel@tonic-gate char *scn_name; 1120Sstevel@tonic-gate char *locale; 1130Sstevel@tonic-gate int opt; 1140Sstevel@tonic-gate int i; 1150Sstevel@tonic-gate 1160Sstevel@tonic-gate (void) setlocale(LC_ALL, ""); 1170Sstevel@tonic-gate 1180Sstevel@tonic-gate #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */ 1190Sstevel@tonic-gate #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */ 1200Sstevel@tonic-gate #endif 1210Sstevel@tonic-gate (void) textdomain(TEXT_DOMAIN); 1220Sstevel@tonic-gate 1230Sstevel@tonic-gate locale = setlocale(LC_CTYPE, NULL); 1240Sstevel@tonic-gate if ((strcmp(locale, "C") == 0) || 1250Sstevel@tonic-gate (strcmp(locale, "POSIX") == 0)) { 1260Sstevel@tonic-gate isClocale = 1; 1270Sstevel@tonic-gate } 1280Sstevel@tonic-gate 1290Sstevel@tonic-gate /* check for non-standard "-" option */ 1300Sstevel@tonic-gate for (i = 1; i < argc; i++) { 1310Sstevel@tonic-gate if (strcmp(argv[i], "-") == 0) { 1320Sstevel@tonic-gate aflg++; 1330Sstevel@tonic-gate while (i < argc) { 1340Sstevel@tonic-gate argv[i] = argv[i+1]; 1350Sstevel@tonic-gate i++; 1360Sstevel@tonic-gate } 1370Sstevel@tonic-gate argc--; 1380Sstevel@tonic-gate } 1390Sstevel@tonic-gate } 1400Sstevel@tonic-gate 1410Sstevel@tonic-gate /* get options */ 1420Sstevel@tonic-gate while ((opt = getopt(argc, argv, "1234567890an:ot:")) != -1) { 1430Sstevel@tonic-gate switch (opt) { 1440Sstevel@tonic-gate case 'a': 1450Sstevel@tonic-gate aflg++; 1460Sstevel@tonic-gate break; 1470Sstevel@tonic-gate 1480Sstevel@tonic-gate case 'n': 1490Sstevel@tonic-gate minlength = (int)strtol(optarg, (char **)NULL, 1500Sstevel@tonic-gate 10); 1510Sstevel@tonic-gate break; 1520Sstevel@tonic-gate 1530Sstevel@tonic-gate case 'o': 1540Sstevel@tonic-gate tflg++; 1550Sstevel@tonic-gate t_format = 'd'; 1560Sstevel@tonic-gate break; 1570Sstevel@tonic-gate 1580Sstevel@tonic-gate case 't': 1590Sstevel@tonic-gate tflg++; 1600Sstevel@tonic-gate t_format = *optarg; 1610Sstevel@tonic-gate if (t_format != 'd' && t_format != 'o' && 1620Sstevel@tonic-gate t_format != 'x') 1630Sstevel@tonic-gate { 1640Sstevel@tonic-gate (void) fprintf(stderr, 1650Sstevel@tonic-gate gettext("Invalid format\n")); 1660Sstevel@tonic-gate Usage(); 1670Sstevel@tonic-gate } 1680Sstevel@tonic-gate break; 1690Sstevel@tonic-gate case '0': 1700Sstevel@tonic-gate case '1': 1710Sstevel@tonic-gate case '2': 1720Sstevel@tonic-gate case '3': 1730Sstevel@tonic-gate case '4': 1740Sstevel@tonic-gate case '5': 1750Sstevel@tonic-gate case '6': 1760Sstevel@tonic-gate case '7': 1770Sstevel@tonic-gate case '8': 1780Sstevel@tonic-gate case '9': 1790Sstevel@tonic-gate minlength *= 10; 1800Sstevel@tonic-gate minlength += opt - '0'; 1810Sstevel@tonic-gate break; 1820Sstevel@tonic-gate 1830Sstevel@tonic-gate default: 1840Sstevel@tonic-gate Usage(); 1850Sstevel@tonic-gate } 1860Sstevel@tonic-gate } 1870Sstevel@tonic-gate 1880Sstevel@tonic-gate /* if min string not specified, use default */ 1890Sstevel@tonic-gate if (!minlength) 1900Sstevel@tonic-gate minlength = DEF_MIN_STRING; 1910Sstevel@tonic-gate 1920Sstevel@tonic-gate 1930Sstevel@tonic-gate /* dynamic allocation of char buffer array */ 1940Sstevel@tonic-gate buf = (char *)malloc(BUFSIZ); 1950Sstevel@tonic-gate if (buf == NULL) { 1960Sstevel@tonic-gate (void) fprintf(stderr, gettext("Cannot allocate memory: %s\n"), 1970Sstevel@tonic-gate strerror(errno)); 1980Sstevel@tonic-gate exit(1); 1990Sstevel@tonic-gate } 2000Sstevel@tonic-gate buf_size = BUFSIZ; 2010Sstevel@tonic-gate tbuf = buf; 2020Sstevel@tonic-gate 2030Sstevel@tonic-gate 2040Sstevel@tonic-gate /* for each file operand */ 2050Sstevel@tonic-gate do { 2060Sstevel@tonic-gate if (argv[optind] != NULL) { 2070Sstevel@tonic-gate if (freopen(argv[optind], "r", stdin) == NULL) { 2080Sstevel@tonic-gate perror(argv[optind]); 2090Sstevel@tonic-gate rc = 1; 2100Sstevel@tonic-gate optind++; 2110Sstevel@tonic-gate continue; 2120Sstevel@tonic-gate } 2130Sstevel@tonic-gate optind++; 2140Sstevel@tonic-gate } else 2150Sstevel@tonic-gate aflg++; 2160Sstevel@tonic-gate 2170Sstevel@tonic-gate if (aflg) 2180Sstevel@tonic-gate htype = NOTOUT; 2190Sstevel@tonic-gate else { 2200Sstevel@tonic-gate hsize = fread((char *)&ahdr, sizeof (char), 2210Sstevel@tonic-gate sizeof (ahdr), stdin); 2220Sstevel@tonic-gate htype = ismagic(hsize, &ahdr, stdin); 2230Sstevel@tonic-gate } 2240Sstevel@tonic-gate switch (htype) { 2250Sstevel@tonic-gate case AOUT: 2260Sstevel@tonic-gate (void) fseek(stdin, (long)ADATAPOS(&ahdr), 0); 2270Sstevel@tonic-gate find((long)ahdr.xa_data); 2280Sstevel@tonic-gate continue; 2290Sstevel@tonic-gate 2300Sstevel@tonic-gate case ELF: 2310Sstevel@tonic-gate /* 2320Sstevel@tonic-gate * Will take care of COFF M32 and i386 also 2330Sstevel@tonic-gate * As well as ELF M32, i386 and Sparc (32- and 64-bit) 2340Sstevel@tonic-gate */ 2350Sstevel@tonic-gate 2360Sstevel@tonic-gate fd = fileno(stdin); 2370Sstevel@tonic-gate (void) lseek(fd, 0L, 0); 2380Sstevel@tonic-gate elf = elf_begin(fd, ELF_C_READ, NULL); 2390Sstevel@tonic-gate if (gelf_getehdr(elf, &ehdr) == 2400Sstevel@tonic-gate (GElf_Ehdr *)NULL) { 2410Sstevel@tonic-gate (void) fprintf(stderr, "%s: %s\n", 2420Sstevel@tonic-gate argv[optind-1], elf_errmsg(-1)); 2430Sstevel@tonic-gate (void) elf_end(elf); 2440Sstevel@tonic-gate rc = 1; 2450Sstevel@tonic-gate continue; 2460Sstevel@tonic-gate } 2470Sstevel@tonic-gate scn = 0; 2480Sstevel@tonic-gate while ((scn = elf_nextscn(elf, scn)) != 0) 2490Sstevel@tonic-gate { 2500Sstevel@tonic-gate if (gelf_getshdr(scn, &shdr) == 2510Sstevel@tonic-gate (GElf_Shdr *)0) { 2520Sstevel@tonic-gate (void) fprintf(stderr, 2530Sstevel@tonic-gate "%s: %s\n", argv[optind-1], 2540Sstevel@tonic-gate elf_errmsg(-1)); 2550Sstevel@tonic-gate rc = 1; 2560Sstevel@tonic-gate continue; 2570Sstevel@tonic-gate } 2580Sstevel@tonic-gate if ((scn_name = elf_strptr(elf, 2590Sstevel@tonic-gate ehdr.e_shstrndx, 2600Sstevel@tonic-gate (size_t)shdr.sh_name)) 2610Sstevel@tonic-gate == (char *)NULL) { 2620Sstevel@tonic-gate (void) fprintf(stderr, 2630Sstevel@tonic-gate "%s: %s\n", argv[optind-1], 2640Sstevel@tonic-gate elf_errmsg(-1)); 2650Sstevel@tonic-gate rc = 1; 2660Sstevel@tonic-gate continue; 2670Sstevel@tonic-gate } 2680Sstevel@tonic-gate /* 2690Sstevel@tonic-gate * There is more than one .data section 2700Sstevel@tonic-gate */ 2710Sstevel@tonic-gate 2720Sstevel@tonic-gate if ((strcmp(scn_name, ".rodata") 2730Sstevel@tonic-gate == 0) || 2740Sstevel@tonic-gate (strcmp(scn_name, ".rodata1") 2750Sstevel@tonic-gate == 0) || 2760Sstevel@tonic-gate (strcmp(scn_name, ".data") 2770Sstevel@tonic-gate == 0) || 2780Sstevel@tonic-gate (strcmp(scn_name, ".data1") 2790Sstevel@tonic-gate == 0)) 2800Sstevel@tonic-gate { 2810Sstevel@tonic-gate (void) fseek(stdin, 2820Sstevel@tonic-gate (long)shdr.sh_offset, 0); 2830Sstevel@tonic-gate find((long)shdr.sh_size); 2840Sstevel@tonic-gate } 2850Sstevel@tonic-gate } 2860Sstevel@tonic-gate continue; 2870Sstevel@tonic-gate 2880Sstevel@tonic-gate case NOTOUT: 2890Sstevel@tonic-gate default: 2900Sstevel@tonic-gate if (!aflg) 2910Sstevel@tonic-gate (void) fseek(stdin, (long)0, 0); 2920Sstevel@tonic-gate find(LONG_MAX); 2930Sstevel@tonic-gate continue; 2940Sstevel@tonic-gate } 2950Sstevel@tonic-gate } while (argv[optind] != NULL); 2960Sstevel@tonic-gate 2970Sstevel@tonic-gate return (rc); 2980Sstevel@tonic-gate } 2990Sstevel@tonic-gate 3000Sstevel@tonic-gate 3010Sstevel@tonic-gate static void 3020Sstevel@tonic-gate find(cnt) 3030Sstevel@tonic-gate long cnt; 3040Sstevel@tonic-gate { 3050Sstevel@tonic-gate int c; 3060Sstevel@tonic-gate int cc; 3070Sstevel@tonic-gate int cr; 3080Sstevel@tonic-gate 3090Sstevel@tonic-gate cc = 0; 3100Sstevel@tonic-gate for (c = ~EOF; (cnt > 0) && (c != EOF); cnt--) { 3110Sstevel@tonic-gate c = getc(stdin); 3120Sstevel@tonic-gate if (!(cr = dirt(c, cc))) { 3130Sstevel@tonic-gate if (cc >= minlength) { 3140Sstevel@tonic-gate if (tflg) { 3150Sstevel@tonic-gate switch (t_format) { 3160Sstevel@tonic-gate case 'd': 3170Sstevel@tonic-gate (void) printf("%7ld ", 3180Sstevel@tonic-gate ftell(stdin) - cc - 1); 3190Sstevel@tonic-gate break; 3200Sstevel@tonic-gate 3210Sstevel@tonic-gate case 'o': 3220Sstevel@tonic-gate (void) printf("%7lo ", 3230Sstevel@tonic-gate ftell(stdin) - cc - 1); 3240Sstevel@tonic-gate break; 3250Sstevel@tonic-gate 3260Sstevel@tonic-gate case 'x': 3270Sstevel@tonic-gate (void) printf("%7lx ", 3280Sstevel@tonic-gate ftell(stdin) - cc - 1); 3290Sstevel@tonic-gate break; 3300Sstevel@tonic-gate } 3310Sstevel@tonic-gate } 3320Sstevel@tonic-gate 3330Sstevel@tonic-gate if (cc >= buf_size) 3340Sstevel@tonic-gate buf[buf_size-1] = '\0'; 3350Sstevel@tonic-gate else 3360Sstevel@tonic-gate buf[cc] = '\0'; 3370Sstevel@tonic-gate (void) puts(buf); 3380Sstevel@tonic-gate } 3390Sstevel@tonic-gate cc = 0; 3400Sstevel@tonic-gate } 3410Sstevel@tonic-gate cc += cr; 3420Sstevel@tonic-gate } 3430Sstevel@tonic-gate } 3440Sstevel@tonic-gate 3450Sstevel@tonic-gate static int 3460Sstevel@tonic-gate dirt(c, cc) 3470Sstevel@tonic-gate int c; 3480Sstevel@tonic-gate int cc; 3490Sstevel@tonic-gate { 3500Sstevel@tonic-gate char mbuf[MB_LEN_MAX + 1]; 3510Sstevel@tonic-gate int len, len1, i; 3520Sstevel@tonic-gate wchar_t wc; 3530Sstevel@tonic-gate int r_val; 3540Sstevel@tonic-gate 3550Sstevel@tonic-gate if (isascii(c)) { 3560Sstevel@tonic-gate if (isprint(c)) { 3570Sstevel@tonic-gate /* 3580Sstevel@tonic-gate * If character count is greater than dynamic 3590Sstevel@tonic-gate * char buffer size, then increase char buffer size. 3600Sstevel@tonic-gate */ 3610Sstevel@tonic-gate if (cc >= (buf_size-2)) { 3620Sstevel@tonic-gate if (tbuf != NULL) { 3630Sstevel@tonic-gate buf_size += BUFSIZ; 3640Sstevel@tonic-gate tbuf = (char *)realloc(buf, buf_size); 3650Sstevel@tonic-gate if (tbuf == NULL) { 3660Sstevel@tonic-gate (void) fprintf(stderr, 3670Sstevel@tonic-gate gettext("Cannot allocate memory: %s\n"), 3680Sstevel@tonic-gate strerror(errno)); 3690Sstevel@tonic-gate buf_size -= BUFSIZ; 3700Sstevel@tonic-gate rc = 1; 3710Sstevel@tonic-gate return (0); 3720Sstevel@tonic-gate } else { 3730Sstevel@tonic-gate buf = tbuf; 3740Sstevel@tonic-gate } 3750Sstevel@tonic-gate } else { 3760Sstevel@tonic-gate return (0); 3770Sstevel@tonic-gate } 3780Sstevel@tonic-gate } 3790Sstevel@tonic-gate buf[cc] = c; 3800Sstevel@tonic-gate return (1); 3810Sstevel@tonic-gate } 3820Sstevel@tonic-gate return (0); 3830Sstevel@tonic-gate } 3840Sstevel@tonic-gate 3850Sstevel@tonic-gate if (isClocale) 3860Sstevel@tonic-gate return (0); 3870Sstevel@tonic-gate 3880Sstevel@tonic-gate r_val = 0; 3890Sstevel@tonic-gate mbuf[0] = c; 3900Sstevel@tonic-gate for (len = 1; len < (unsigned int)MB_CUR_MAX; len++) { 3910Sstevel@tonic-gate if ((signed char) 3920Sstevel@tonic-gate (mbuf[len] = getc(stdin)) == -1) 3930Sstevel@tonic-gate break; 3940Sstevel@tonic-gate } 3950Sstevel@tonic-gate mbuf[len] = 0; 3960Sstevel@tonic-gate 3970Sstevel@tonic-gate if ((len1 = mbtowc(&wc, mbuf, len)) <= 0) { 3980Sstevel@tonic-gate len1 = 1; 3990Sstevel@tonic-gate goto _unget; 4000Sstevel@tonic-gate } 4010Sstevel@tonic-gate 4020Sstevel@tonic-gate if (iswprint(wc)) { 4030Sstevel@tonic-gate if ((cc + len1) >= (buf_size-2)) { 4040Sstevel@tonic-gate if (tbuf != NULL) { 4050Sstevel@tonic-gate buf_size += BUFSIZ; 4060Sstevel@tonic-gate tbuf = (char *)realloc(buf, buf_size); 4070Sstevel@tonic-gate if (tbuf == NULL) { 4080Sstevel@tonic-gate (void) fprintf(stderr, 4090Sstevel@tonic-gate gettext("Cannot allocate memory: %s\n"), 4100Sstevel@tonic-gate strerror(errno)); 4110Sstevel@tonic-gate buf_size -= BUFSIZ; 4120Sstevel@tonic-gate rc = 1; 4130Sstevel@tonic-gate return (0); 4140Sstevel@tonic-gate } 4150Sstevel@tonic-gate buf = tbuf; 4160Sstevel@tonic-gate } else { 4170Sstevel@tonic-gate return (0); 4180Sstevel@tonic-gate } 4190Sstevel@tonic-gate } 4200Sstevel@tonic-gate for (i = 0; i < len1; i++, cc++) 4210Sstevel@tonic-gate buf[cc] = mbuf[i]; 4220Sstevel@tonic-gate r_val = len1; 4230Sstevel@tonic-gate } 4240Sstevel@tonic-gate 4250Sstevel@tonic-gate _unget: 4260Sstevel@tonic-gate for (len--; len >= len1; len--) 4270Sstevel@tonic-gate (void) ungetc(mbuf[len], stdin); 4280Sstevel@tonic-gate return (r_val); 4290Sstevel@tonic-gate } 4300Sstevel@tonic-gate 4310Sstevel@tonic-gate 4320Sstevel@tonic-gate static int 4330Sstevel@tonic-gate ismagic(hsize, hdr, fp) 4340Sstevel@tonic-gate int hsize; 4350Sstevel@tonic-gate struct aexec *hdr; 4360Sstevel@tonic-gate FILE *fp; 4370Sstevel@tonic-gate { 4380Sstevel@tonic-gate switch (hdr->xa_magic) { 4390Sstevel@tonic-gate case A_MAGIC1: 4400Sstevel@tonic-gate case A_MAGIC2: 4410Sstevel@tonic-gate case A_MAGIC3: 4420Sstevel@tonic-gate case A_MAGIC4: 4430Sstevel@tonic-gate if (hsize < sizeof (struct aexec)) 4440Sstevel@tonic-gate return (NOTOUT); 4450Sstevel@tonic-gate else 4460Sstevel@tonic-gate return (AOUT); 4470Sstevel@tonic-gate default: 4480Sstevel@tonic-gate break; 4490Sstevel@tonic-gate } 4500Sstevel@tonic-gate return (tryelf(fp)); 4510Sstevel@tonic-gate } 4520Sstevel@tonic-gate 4530Sstevel@tonic-gate 4540Sstevel@tonic-gate static int 4550Sstevel@tonic-gate tryelf(fp) 4560Sstevel@tonic-gate FILE *fp; 4570Sstevel@tonic-gate { 4580Sstevel@tonic-gate int fd; 4590Sstevel@tonic-gate Elf *elf; 4600Sstevel@tonic-gate GElf_Ehdr ehdr; 4610Sstevel@tonic-gate 4620Sstevel@tonic-gate fd = fileno(fp); 4630Sstevel@tonic-gate 4640Sstevel@tonic-gate if ((elf_version(EV_CURRENT)) == EV_NONE) { 4650Sstevel@tonic-gate (void) fprintf(stderr, "%s\n", elf_errmsg(-1)); 4660Sstevel@tonic-gate return (NOTOUT); 4670Sstevel@tonic-gate } 4680Sstevel@tonic-gate 4690Sstevel@tonic-gate (void) lseek(fd, 0L, 0); 4700Sstevel@tonic-gate 4710Sstevel@tonic-gate if ((elf = elf_begin(fd, ELF_C_READ, NULL)) == NULL) { 4720Sstevel@tonic-gate (void) fprintf(stderr, "%s\n", elf_errmsg(-1)); 4730Sstevel@tonic-gate return (NOTOUT); 4740Sstevel@tonic-gate } 4750Sstevel@tonic-gate 4760Sstevel@tonic-gate switch (elf_kind(elf)) { 4770Sstevel@tonic-gate case ELF_K_AR: 4780Sstevel@tonic-gate /* 4790Sstevel@tonic-gate * This should try to run strings on each element 4800Sstevel@tonic-gate * of the archive. For now, just search entire 4810Sstevel@tonic-gate * file (-a), as strings has always done 4820Sstevel@tonic-gate * for archives. 4830Sstevel@tonic-gate */ 4840Sstevel@tonic-gate case ELF_K_NONE: 4850Sstevel@tonic-gate (void) elf_end(elf); 4860Sstevel@tonic-gate return (NOTOUT); 4870Sstevel@tonic-gate } 4880Sstevel@tonic-gate 4890Sstevel@tonic-gate if (gelf_getehdr(elf, &ehdr) == (GElf_Ehdr *)NULL) { 4900Sstevel@tonic-gate (void) fprintf(stderr, "%s\n", elf_errmsg(-1)); 4910Sstevel@tonic-gate (void) elf_end(elf); 4920Sstevel@tonic-gate return (NOTOUT); 4930Sstevel@tonic-gate } 4940Sstevel@tonic-gate 4950Sstevel@tonic-gate if ((ehdr.e_type == ET_CORE) || (ehdr.e_type == ET_NONE)) { 4960Sstevel@tonic-gate (void) elf_end(elf); 4970Sstevel@tonic-gate return (NOTOUT); 4980Sstevel@tonic-gate } 4990Sstevel@tonic-gate 5000Sstevel@tonic-gate (void) elf_end(elf); 5010Sstevel@tonic-gate 5020Sstevel@tonic-gate return (ELF); 5030Sstevel@tonic-gate 5040Sstevel@tonic-gate } 5050Sstevel@tonic-gate 5060Sstevel@tonic-gate 5070Sstevel@tonic-gate static void 5080Sstevel@tonic-gate Usage() 5090Sstevel@tonic-gate { 5100Sstevel@tonic-gate (void) fprintf(stderr, gettext( 5110Sstevel@tonic-gate "Usage: strings [-|-a] [-t format] [-n #] [file ...]\n" 5120Sstevel@tonic-gate " strings [-|-a] [-o] [-#] [file ...]\n")); 5130Sstevel@tonic-gate exit(1); 5140Sstevel@tonic-gate } 515