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 5*1618Srie * Common Development and Distribution License (the "License"). 6*1618Srie * You may not use this file except in compliance with the License. 70Sstevel@tonic-gate * 80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 100Sstevel@tonic-gate * See the License for the specific language governing permissions 110Sstevel@tonic-gate * and limitations under the License. 120Sstevel@tonic-gate * 130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 180Sstevel@tonic-gate * 190Sstevel@tonic-gate * CDDL HEADER END 200Sstevel@tonic-gate */ 21*1618Srie 220Sstevel@tonic-gate /* 230Sstevel@tonic-gate * Copyright (c) 1988 AT&T 240Sstevel@tonic-gate * All Rights Reserved 250Sstevel@tonic-gate * 26*1618Srie * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 270Sstevel@tonic-gate * Use is subject to license terms. 280Sstevel@tonic-gate */ 290Sstevel@tonic-gate 300Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 310Sstevel@tonic-gate 320Sstevel@tonic-gate #include <stdio.h> 330Sstevel@tonic-gate #include <stdlib.h> 340Sstevel@tonic-gate #include <locale.h> 350Sstevel@tonic-gate #include <unistd.h> 360Sstevel@tonic-gate #include <libelf.h> 370Sstevel@tonic-gate #include <link.h> 380Sstevel@tonic-gate #include <sys/elf_M32.h> 390Sstevel@tonic-gate #include <sys/elf_386.h> 400Sstevel@tonic-gate #include <sys/elf_SPARC.h> 41*1618Srie #include <sys/elf_amd64.h> 420Sstevel@tonic-gate #include <sys/machelf.h> 430Sstevel@tonic-gate #include <fcntl.h> 440Sstevel@tonic-gate #include <sys/stat.h> 450Sstevel@tonic-gate #include <errno.h> 460Sstevel@tonic-gate #include <string.h> 470Sstevel@tonic-gate #include "sgs.h" 480Sstevel@tonic-gate #include "conv.h" 490Sstevel@tonic-gate #include "dump.h" 500Sstevel@tonic-gate 510Sstevel@tonic-gate 520Sstevel@tonic-gate #define OPTSTR "agcd:fhn:oprstvCLT:V?" /* option string for getopt() */ 530Sstevel@tonic-gate 540Sstevel@tonic-gate const char *UNKNOWN = "<unknown>"; 550Sstevel@tonic-gate 560Sstevel@tonic-gate static SCNTAB *p_symtab, *p_head_scns, *p_dynsym; 570Sstevel@tonic-gate 580Sstevel@tonic-gate static int 590Sstevel@tonic-gate x_flag = 0, /* option requires section header table */ 600Sstevel@tonic-gate z_flag = 0, /* process files within an archive */ 610Sstevel@tonic-gate rn_flag = 0; /* dump named relocation information */ 620Sstevel@tonic-gate 630Sstevel@tonic-gate static int 640Sstevel@tonic-gate /* flags: ?_flag corresponds to ? option */ 650Sstevel@tonic-gate a_flag = 0, /* dump archive header of each member of archive */ 660Sstevel@tonic-gate g_flag = 0, /* dump archive symbol table */ 670Sstevel@tonic-gate c_flag = 0, /* dump the string table */ 680Sstevel@tonic-gate d_flag = 0, /* dump range of sections */ 690Sstevel@tonic-gate f_flag = 0, /* dump each file header */ 700Sstevel@tonic-gate h_flag = 0, /* dump section headers */ 710Sstevel@tonic-gate n_flag = 0, /* dump named section */ 720Sstevel@tonic-gate o_flag = 0, /* dump each program execution header */ 730Sstevel@tonic-gate r_flag = 0, /* dump relocation information */ 740Sstevel@tonic-gate s_flag = 0, /* dump section contents */ 750Sstevel@tonic-gate t_flag = 0, /* dump symbol table entries */ 760Sstevel@tonic-gate C_flag = 0, /* dump decoded C++ symbol names */ 770Sstevel@tonic-gate L_flag = 0, /* dump dynamic linking information */ 780Sstevel@tonic-gate T_flag = 0, /* dump symbol table range */ 790Sstevel@tonic-gate V_flag = 0; /* dump version information */ 800Sstevel@tonic-gate 810Sstevel@tonic-gate int p_flag = 0, /* suppress printing of headings */ 820Sstevel@tonic-gate v_flag = 0; /* print information in verbose form */ 830Sstevel@tonic-gate 840Sstevel@tonic-gate static int 850Sstevel@tonic-gate d_low = 0, /* range for use with -d */ 860Sstevel@tonic-gate d_hi = 0, 870Sstevel@tonic-gate d_num = 0; 880Sstevel@tonic-gate 890Sstevel@tonic-gate static int 900Sstevel@tonic-gate T_low = 0, /* range for use with -T */ 910Sstevel@tonic-gate T_hi = 0, 920Sstevel@tonic-gate T_num = 0; 930Sstevel@tonic-gate 940Sstevel@tonic-gate static char *name = NULL; /* for use with -n option */ 950Sstevel@tonic-gate char *prog_name; 960Sstevel@tonic-gate static int errflag = 0; 970Sstevel@tonic-gate 980Sstevel@tonic-gate static struct stab_list_s { 990Sstevel@tonic-gate struct stab_list_s *next; 1000Sstevel@tonic-gate char *strings; 1010Sstevel@tonic-gate size_t size; 1020Sstevel@tonic-gate } *StringTableList = (void *)0; 1030Sstevel@tonic-gate 1040Sstevel@tonic-gate extern void ar_sym_read(); 1050Sstevel@tonic-gate extern void dump_exec_header(); 1060Sstevel@tonic-gate 1070Sstevel@tonic-gate 1080Sstevel@tonic-gate /* 1090Sstevel@tonic-gate * Get the section descriptor and set the size of the 1100Sstevel@tonic-gate * data returned. Data is byte-order converted. 1110Sstevel@tonic-gate */ 1120Sstevel@tonic-gate void * 1130Sstevel@tonic-gate get_scndata(Elf_Scn *fd_scn, size_t *size) 1140Sstevel@tonic-gate { 1150Sstevel@tonic-gate Elf_Data *p_data; 1160Sstevel@tonic-gate 1170Sstevel@tonic-gate p_data = 0; 1180Sstevel@tonic-gate if ((p_data = elf_getdata(fd_scn, p_data)) == 0 || 1190Sstevel@tonic-gate p_data->d_size == 0) { 1200Sstevel@tonic-gate return (NULL); 1210Sstevel@tonic-gate } 1220Sstevel@tonic-gate *size = p_data->d_size; 1230Sstevel@tonic-gate return (p_data->d_buf); 1240Sstevel@tonic-gate } 1250Sstevel@tonic-gate 1260Sstevel@tonic-gate /* 1270Sstevel@tonic-gate * Get the section descriptor and set the size of the 1280Sstevel@tonic-gate * data returned. Data is raw (i.e., not byte-order converted). 1290Sstevel@tonic-gate */ 1300Sstevel@tonic-gate static void * 1310Sstevel@tonic-gate get_rawscn(Elf_Scn *fd_scn, size_t *size) 1320Sstevel@tonic-gate { 1330Sstevel@tonic-gate Elf_Data *p_data; 1340Sstevel@tonic-gate 1350Sstevel@tonic-gate p_data = 0; 1360Sstevel@tonic-gate if ((p_data = elf_rawdata(fd_scn, p_data)) == 0 || 1370Sstevel@tonic-gate p_data->d_size == 0) { 1380Sstevel@tonic-gate return (NULL); 1390Sstevel@tonic-gate } 1400Sstevel@tonic-gate 1410Sstevel@tonic-gate *size = p_data->d_size; 1420Sstevel@tonic-gate return (p_data->d_buf); 1430Sstevel@tonic-gate } 1440Sstevel@tonic-gate 1450Sstevel@tonic-gate /* 1460Sstevel@tonic-gate * Print out a usage message in short form when program is invoked 1470Sstevel@tonic-gate * with insufficient or no arguments, and in long form when given 1480Sstevel@tonic-gate * either a ? or an invalid option. 1490Sstevel@tonic-gate */ 1500Sstevel@tonic-gate static void 1510Sstevel@tonic-gate usage() 1520Sstevel@tonic-gate { 1530Sstevel@tonic-gate (void) fprintf(stderr, 1540Sstevel@tonic-gate "Usage: %s [-%s] file(s) ...\n", prog_name, OPTSTR); 1550Sstevel@tonic-gate if (errflag) { 1560Sstevel@tonic-gate (void) fprintf(stderr, 1570Sstevel@tonic-gate "\t\t[-a dump archive header of each member of archive]\n\ 1580Sstevel@tonic-gate [-g dump archive global symbol table]\n\ 1590Sstevel@tonic-gate [-c dump the string table]\n\ 1600Sstevel@tonic-gate [-d dump range of sections]\n\ 1610Sstevel@tonic-gate [-f dump each file header]\n\ 1620Sstevel@tonic-gate [-h dump section headers]\n\ 1630Sstevel@tonic-gate [-n dump named section]\n\ 1640Sstevel@tonic-gate [-o dump each program execution header]\n\ 1650Sstevel@tonic-gate [-p suppress printing of headings]\n\ 1660Sstevel@tonic-gate [-r dump relocation information]\n\ 1670Sstevel@tonic-gate [-s dump section contents]\n\ 1680Sstevel@tonic-gate [-t dump symbol table entries]\n\ 1690Sstevel@tonic-gate [-v print information in verbose form]\n\ 1700Sstevel@tonic-gate [-C dump decoded C++ symbol names]\n\ 1710Sstevel@tonic-gate [-L dump the .dynamic structure]\n\ 1720Sstevel@tonic-gate [-T dump symbol table range]\n\ 1730Sstevel@tonic-gate [-V dump version information]\n"); 1740Sstevel@tonic-gate } 1750Sstevel@tonic-gate } 1760Sstevel@tonic-gate 1770Sstevel@tonic-gate /* 1780Sstevel@tonic-gate * Set a range. Input is a character string, a lower 1790Sstevel@tonic-gate * bound and an upper bound. This function converts 1800Sstevel@tonic-gate * a character string into its correct integer values, 1810Sstevel@tonic-gate * setting the first value as the lower bound, and 1820Sstevel@tonic-gate * the second value as the upper bound. If more values 1830Sstevel@tonic-gate * are given they are ignored with a warning. 1840Sstevel@tonic-gate */ 1850Sstevel@tonic-gate static void 1860Sstevel@tonic-gate set_range(char *s, int *low, int *high) 1870Sstevel@tonic-gate { 1880Sstevel@tonic-gate char *w; 1890Sstevel@tonic-gate char *lasts; 1900Sstevel@tonic-gate 1910Sstevel@tonic-gate while ((w = strtok_r(s, ",", &lasts)) != NULL) { 1920Sstevel@tonic-gate if (!(*low)) 1930Sstevel@tonic-gate /* LINTED */ 1940Sstevel@tonic-gate *low = (int)atol(w); 1950Sstevel@tonic-gate else 1960Sstevel@tonic-gate if (!(*high)) 1970Sstevel@tonic-gate /* LINTED */ 1980Sstevel@tonic-gate *high = (int)atol(w); 1990Sstevel@tonic-gate else { 2000Sstevel@tonic-gate (void) fprintf(stderr, 2010Sstevel@tonic-gate "%s: too many arguments - %s ignored\n", 2020Sstevel@tonic-gate prog_name, w); 2030Sstevel@tonic-gate return; 2040Sstevel@tonic-gate } 2050Sstevel@tonic-gate s = NULL; 2060Sstevel@tonic-gate } /* end while */ 2070Sstevel@tonic-gate } 2080Sstevel@tonic-gate 2090Sstevel@tonic-gate 2100Sstevel@tonic-gate /* 2110Sstevel@tonic-gate * Print static shared library information. 2120Sstevel@tonic-gate */ 2130Sstevel@tonic-gate static void 2140Sstevel@tonic-gate print_static(SCNTAB *l_scns, char *filename) 2150Sstevel@tonic-gate { 2160Sstevel@tonic-gate size_t section_size; 2170Sstevel@tonic-gate unsigned char *strtab; 2180Sstevel@tonic-gate unsigned char *path, buf[1024]; 2190Sstevel@tonic-gate unsigned long *temp; 2200Sstevel@tonic-gate unsigned long total, topath; 2210Sstevel@tonic-gate 2220Sstevel@tonic-gate (void) printf("\n **** STATIC SHARED LIBRARY INFORMATION ****\n"); 2230Sstevel@tonic-gate (void) printf("\n%s:\n", filename); 2240Sstevel@tonic-gate (void) printf("\t"); 2250Sstevel@tonic-gate section_size = 0; 2260Sstevel@tonic-gate if ((strtab = (unsigned char *) 2270Sstevel@tonic-gate get_scndata(l_scns->p_sd, §ion_size)) == NULL) { 2280Sstevel@tonic-gate return; 2290Sstevel@tonic-gate } 2300Sstevel@tonic-gate 2310Sstevel@tonic-gate while (section_size != 0) { 2320Sstevel@tonic-gate /* LINTED */ 2330Sstevel@tonic-gate temp = (unsigned long *)strtab; 2340Sstevel@tonic-gate total = temp[0]; 2350Sstevel@tonic-gate topath = temp[1]; 2360Sstevel@tonic-gate path = strtab + (topath*sizeof (long)); 2370Sstevel@tonic-gate (void) strncpy((char *)buf, (char *)path, 2380Sstevel@tonic-gate (total - topath)*sizeof (long)); 2390Sstevel@tonic-gate (void) fprintf(stdout, "%s\n", buf); 2400Sstevel@tonic-gate strtab += total*sizeof (long); 2410Sstevel@tonic-gate section_size -= (total*sizeof (long)); 2420Sstevel@tonic-gate } 2430Sstevel@tonic-gate } 2440Sstevel@tonic-gate 2450Sstevel@tonic-gate /* 2460Sstevel@tonic-gate * Print raw data in hexidecimal. Input is the section data to 2470Sstevel@tonic-gate * be printed out and the size of the data. Output is relative 2480Sstevel@tonic-gate * to a table lookup in dumpmap.h. 2490Sstevel@tonic-gate */ 2500Sstevel@tonic-gate static void 2510Sstevel@tonic-gate print_rawdata(unsigned char *p_sec, size_t size) 2520Sstevel@tonic-gate { 2530Sstevel@tonic-gate size_t j; 2540Sstevel@tonic-gate size_t count; 2550Sstevel@tonic-gate 2560Sstevel@tonic-gate count = 1; 2570Sstevel@tonic-gate 2580Sstevel@tonic-gate (void) printf("\t"); 2590Sstevel@tonic-gate for (j = size/sizeof (short); j != 0; --j, ++count) { 2600Sstevel@tonic-gate (void) printf("%.2x %.2x ", p_sec[0], p_sec[1]); 2610Sstevel@tonic-gate p_sec += 2; 2620Sstevel@tonic-gate if (count == 12) { 2630Sstevel@tonic-gate (void) printf("\n\t"); 2640Sstevel@tonic-gate count = 0; 2650Sstevel@tonic-gate } 2660Sstevel@tonic-gate } 2670Sstevel@tonic-gate 2680Sstevel@tonic-gate /* 2690Sstevel@tonic-gate * take care of last byte if odd byte section 2700Sstevel@tonic-gate */ 2710Sstevel@tonic-gate if ((size & 0x1L) == 1L) 2720Sstevel@tonic-gate (void) printf("%.2x", *p_sec); 2730Sstevel@tonic-gate (void) printf("\n"); 2740Sstevel@tonic-gate } 2750Sstevel@tonic-gate 2760Sstevel@tonic-gate 2770Sstevel@tonic-gate 2780Sstevel@tonic-gate /* 2790Sstevel@tonic-gate * Print relocation data of type SHT_RELA 2800Sstevel@tonic-gate * If d_flag, print data corresponding only to 2810Sstevel@tonic-gate * the section or range of sections specified. 2820Sstevel@tonic-gate * If n_flag, print data corresponding only to 2830Sstevel@tonic-gate * the named section. 2840Sstevel@tonic-gate */ 2850Sstevel@tonic-gate static void 2860Sstevel@tonic-gate print_rela(Elf *elf_file, SCNTAB *p_scns, Elf_Data *rdata, Elf_Data *sym_data, 2870Sstevel@tonic-gate GElf_Ehdr * p_ehdr, size_t reloc_size, size_t sym_size, char *filename, 2880Sstevel@tonic-gate SCNTAB *reloc_symtab) 2890Sstevel@tonic-gate { 2900Sstevel@tonic-gate GElf_Rela rela; 2910Sstevel@tonic-gate GElf_Sym sym; 2920Sstevel@tonic-gate size_t no_entries; 2930Sstevel@tonic-gate size_t rel_entsize; 2940Sstevel@tonic-gate size_t no_syms; 2950Sstevel@tonic-gate int type, symid; 2960Sstevel@tonic-gate static int n_title = 0; 2970Sstevel@tonic-gate int ndx = 0; 2980Sstevel@tonic-gate char *sym_name; 2990Sstevel@tonic-gate int adj = 0; 3000Sstevel@tonic-gate 3010Sstevel@tonic-gate if (gelf_getclass(elf_file) == ELFCLASS64) 302*1618Srie adj = 8; 3030Sstevel@tonic-gate 3040Sstevel@tonic-gate rel_entsize = p_scns->p_shdr.sh_entsize; 3050Sstevel@tonic-gate if ((rel_entsize == 0) || 3060Sstevel@tonic-gate (rel_entsize > p_scns->p_shdr.sh_size)) { 3070Sstevel@tonic-gate rel_entsize = gelf_fsize(elf_file, ELF_T_RELA, 1, 3080Sstevel@tonic-gate EV_CURRENT); 3090Sstevel@tonic-gate } 3100Sstevel@tonic-gate no_entries = reloc_size / rel_entsize; 3110Sstevel@tonic-gate 3120Sstevel@tonic-gate no_syms = sym_size / gelf_fsize(elf_file, ELF_T_SYM, 1, EV_CURRENT); 3130Sstevel@tonic-gate while (no_entries--) { 3140Sstevel@tonic-gate (void) gelf_getrela(rdata, ndx, &rela); 3150Sstevel@tonic-gate /* LINTED */ 3160Sstevel@tonic-gate type = (int)GELF_R_TYPE(rela.r_info); 3170Sstevel@tonic-gate /* LINTED */ 3180Sstevel@tonic-gate symid = (int)GELF_R_SYM(rela.r_info); 3190Sstevel@tonic-gate /* LINTED */ 3200Sstevel@tonic-gate if ((symid > (no_syms - 1)) || (symid < 0)) { 3210Sstevel@tonic-gate (void) fprintf(stderr, "%s: %s: invalid symbol table " 3220Sstevel@tonic-gate "offset - %d - in %s\n", prog_name, filename, 3230Sstevel@tonic-gate symid, p_scns->scn_name); 3240Sstevel@tonic-gate ndx++; 3250Sstevel@tonic-gate continue; 3260Sstevel@tonic-gate } 3270Sstevel@tonic-gate (void) gelf_getsym(sym_data, symid, &sym); 3280Sstevel@tonic-gate sym_name = (char *)elf_strptr(elf_file, 3290Sstevel@tonic-gate reloc_symtab->p_shdr.sh_link, sym.st_name); 3300Sstevel@tonic-gate if (sym_name == NULL) 3310Sstevel@tonic-gate sym_name = (char *)UNKNOWN; 3320Sstevel@tonic-gate if (r_flag && rn_flag) { 3330Sstevel@tonic-gate if (strcmp(name, p_scns->scn_name) != 0) { 3340Sstevel@tonic-gate ndx++; 3350Sstevel@tonic-gate continue; 3360Sstevel@tonic-gate } 3370Sstevel@tonic-gate if (!n_title) { 3380Sstevel@tonic-gate (void) printf("\n%s:\n", p_scns->scn_name); 3390Sstevel@tonic-gate (void) printf("%-*s%-*s%-*s%s\n\n", 3400Sstevel@tonic-gate 12 + adj, "Offset", 22, "Symndx", 3410Sstevel@tonic-gate 16, "Type", "Addend"); 3420Sstevel@tonic-gate n_title = 1; 3430Sstevel@tonic-gate } 3440Sstevel@tonic-gate } 3450Sstevel@tonic-gate if (d_flag) { 3460Sstevel@tonic-gate if (!d_hi) 3470Sstevel@tonic-gate d_hi = d_low; 3480Sstevel@tonic-gate if ((symid < d_low) || (symid > d_hi)) { 3490Sstevel@tonic-gate ndx++; 3500Sstevel@tonic-gate continue; 3510Sstevel@tonic-gate } 3520Sstevel@tonic-gate } 3530Sstevel@tonic-gate 3540Sstevel@tonic-gate (void) printf("%-#*llx", 12 + adj, EC_XWORD(rela.r_offset)); 3550Sstevel@tonic-gate if (!v_flag) { 3560Sstevel@tonic-gate (void) printf("%-22d%-18d", symid, type); 3570Sstevel@tonic-gate } else { 3580Sstevel@tonic-gate if (strlen(sym_name)) { 3590Sstevel@tonic-gate size_t len = strlen(sym_name) + 1; 3600Sstevel@tonic-gate char tmpstr[10]; 3610Sstevel@tonic-gate if (len > 22) { 3620Sstevel@tonic-gate (void) sprintf(tmpstr, "%%-%ds", 3630Sstevel@tonic-gate /* LINTED */ 3640Sstevel@tonic-gate (int)len); 3650Sstevel@tonic-gate (void) printf(tmpstr, sym_name); 3660Sstevel@tonic-gate } else 3670Sstevel@tonic-gate (void) printf("%-22s", sym_name); 3680Sstevel@tonic-gate } else 3690Sstevel@tonic-gate (void) printf("%-22d", symid); 3700Sstevel@tonic-gate print_reloc_type(p_ehdr->e_machine, type); 3710Sstevel@tonic-gate } 3720Sstevel@tonic-gate (void) printf("%lld\n", EC_SXWORD(rela.r_addend)); 3730Sstevel@tonic-gate ndx++; 3740Sstevel@tonic-gate } 3750Sstevel@tonic-gate } 3760Sstevel@tonic-gate 3770Sstevel@tonic-gate /* 3780Sstevel@tonic-gate * Print relocation data of type SHT_REL. 3790Sstevel@tonic-gate * If d_flag, print data corresponding only to 3800Sstevel@tonic-gate * the section or range of sections specified. 3810Sstevel@tonic-gate * If n_flag, print data corresponding only to 3820Sstevel@tonic-gate * the named section. 3830Sstevel@tonic-gate */ 3840Sstevel@tonic-gate static void 3850Sstevel@tonic-gate print_rel(Elf *elf_file, SCNTAB *p_scns, Elf_Data *rdata, Elf_Data *sym_data, 3860Sstevel@tonic-gate GElf_Ehdr *p_ehdr, size_t reloc_size, size_t sym_size, char *filename, 3870Sstevel@tonic-gate SCNTAB *reloc_symtab) 3880Sstevel@tonic-gate { 3890Sstevel@tonic-gate GElf_Rel rel; 3900Sstevel@tonic-gate GElf_Sym sym; 3910Sstevel@tonic-gate size_t no_entries; 3920Sstevel@tonic-gate size_t rel_entsize; 3930Sstevel@tonic-gate int type, symid; 3940Sstevel@tonic-gate size_t no_syms; 3950Sstevel@tonic-gate static int n_title = 0; 3960Sstevel@tonic-gate int ndx = 0; 3970Sstevel@tonic-gate char *sym_name; 3980Sstevel@tonic-gate int adj = 0; 3990Sstevel@tonic-gate 4000Sstevel@tonic-gate if (gelf_getclass(elf_file) == ELFCLASS64) 401*1618Srie adj = 8; 4020Sstevel@tonic-gate 4030Sstevel@tonic-gate rel_entsize = p_scns->p_shdr.sh_entsize; 4040Sstevel@tonic-gate if ((rel_entsize == 0) || 4050Sstevel@tonic-gate (rel_entsize > p_scns->p_shdr.sh_size)) { 4060Sstevel@tonic-gate rel_entsize = gelf_fsize(elf_file, ELF_T_REL, 1, 4070Sstevel@tonic-gate EV_CURRENT); 4080Sstevel@tonic-gate } 4090Sstevel@tonic-gate no_entries = reloc_size / rel_entsize; 4100Sstevel@tonic-gate 4110Sstevel@tonic-gate no_syms = sym_size / gelf_fsize(elf_file, ELF_T_SYM, 1, EV_CURRENT); 4120Sstevel@tonic-gate while (no_entries--) { 4130Sstevel@tonic-gate (void) gelf_getrel(rdata, ndx, &rel); 4140Sstevel@tonic-gate /* LINTED */ 4150Sstevel@tonic-gate type = (int)GELF_R_TYPE(rel.r_info); 4160Sstevel@tonic-gate /* LINTED */ 4170Sstevel@tonic-gate symid = (int)GELF_R_SYM(rel.r_info); 4180Sstevel@tonic-gate /* LINTED */ 4190Sstevel@tonic-gate if ((symid > (no_syms - 1)) || (symid < 0)) { 4200Sstevel@tonic-gate (void) fprintf(stderr, "%s: %s: invalid symbol table " 4210Sstevel@tonic-gate "offset - %d - in %s\n", prog_name, filename, 4220Sstevel@tonic-gate symid, p_scns->scn_name); 4230Sstevel@tonic-gate ndx++; 4240Sstevel@tonic-gate continue; 4250Sstevel@tonic-gate } 4260Sstevel@tonic-gate (void) gelf_getsym(sym_data, symid, &sym); 4270Sstevel@tonic-gate sym_name = (char *)elf_strptr(elf_file, 4280Sstevel@tonic-gate reloc_symtab->p_shdr.sh_link, sym.st_name); 4290Sstevel@tonic-gate if (sym_name == NULL) 4300Sstevel@tonic-gate sym_name = (char *)UNKNOWN; 4310Sstevel@tonic-gate if (r_flag && rn_flag) { 4320Sstevel@tonic-gate if (strcmp(name, p_scns->scn_name) != 0) { 4330Sstevel@tonic-gate ndx++; 4340Sstevel@tonic-gate continue; 4350Sstevel@tonic-gate } 4360Sstevel@tonic-gate if (!n_title) { 4370Sstevel@tonic-gate (void) printf("\n%s:\n", p_scns->scn_name); 4380Sstevel@tonic-gate (void) printf("%-*s%-*s%s\n\n", 4390Sstevel@tonic-gate 12 + adj, "Offset", 20, "Symndx", "Type"); 4400Sstevel@tonic-gate n_title = 1; 4410Sstevel@tonic-gate } 4420Sstevel@tonic-gate } 4430Sstevel@tonic-gate if (d_flag) { 4440Sstevel@tonic-gate if (!d_hi) 4450Sstevel@tonic-gate d_hi = d_low; 4460Sstevel@tonic-gate if ((symid < d_low) || (symid > d_hi)) { 4470Sstevel@tonic-gate ndx++; 4480Sstevel@tonic-gate continue; 4490Sstevel@tonic-gate } 4500Sstevel@tonic-gate } 4510Sstevel@tonic-gate 4520Sstevel@tonic-gate (void) printf("%-#*llx", 12 + adj, EC_ADDR(rel.r_offset)); 4530Sstevel@tonic-gate if (!v_flag) { 4540Sstevel@tonic-gate (void) printf("%-20d%-18d", symid, type); 4550Sstevel@tonic-gate } else { 4560Sstevel@tonic-gate if (strlen(sym_name)) 4570Sstevel@tonic-gate (void) printf("%-20s", sym_name); 4580Sstevel@tonic-gate else 4590Sstevel@tonic-gate (void) printf("%-20d", sym.st_name); 4600Sstevel@tonic-gate 4610Sstevel@tonic-gate print_reloc_type(p_ehdr->e_machine, type); 4620Sstevel@tonic-gate } 4630Sstevel@tonic-gate (void) printf("\n"); 4640Sstevel@tonic-gate ndx++; 4650Sstevel@tonic-gate } 4660Sstevel@tonic-gate } 4670Sstevel@tonic-gate 4680Sstevel@tonic-gate /* demangle C++ names */ 4690Sstevel@tonic-gate static char * 4700Sstevel@tonic-gate demangled_name(char *s) 4710Sstevel@tonic-gate { 472*1618Srie static char *buf = NULL; 473*1618Srie char *dn; 474*1618Srie size_t len; 4750Sstevel@tonic-gate 4760Sstevel@tonic-gate dn = sgs_demangle(s); 4770Sstevel@tonic-gate 4780Sstevel@tonic-gate /* 4790Sstevel@tonic-gate * If not demangled, just return the symbol name 4800Sstevel@tonic-gate */ 4810Sstevel@tonic-gate if (strcmp(s, dn) == 0) 4820Sstevel@tonic-gate return (s); 4830Sstevel@tonic-gate 4840Sstevel@tonic-gate /* 4850Sstevel@tonic-gate * Demangled. Format it 4860Sstevel@tonic-gate */ 4870Sstevel@tonic-gate if (buf != NULL) 4880Sstevel@tonic-gate free(buf); 4890Sstevel@tonic-gate 490*1618Srie len = strlen(dn) + strlen(s) + 4; 491*1618Srie if ((buf = malloc(len)) == NULL) 4920Sstevel@tonic-gate return (s); 4930Sstevel@tonic-gate 494*1618Srie (void) snprintf(buf, len, "%s\t[%s]", dn, s); 4950Sstevel@tonic-gate return (buf); 4960Sstevel@tonic-gate } 4970Sstevel@tonic-gate 4980Sstevel@tonic-gate /* 4990Sstevel@tonic-gate * Print the symbol table. Input is an ELF file descriptor, a 5000Sstevel@tonic-gate * pointer to the symbol table SCNTAB structure, 5010Sstevel@tonic-gate * the number of symbols, a range of symbols to print, 5020Sstevel@tonic-gate * an index which is the number of the 5030Sstevel@tonic-gate * section in the file, and the filename. The number of sections, 5040Sstevel@tonic-gate * the range, and the index are set in 5050Sstevel@tonic-gate * dump_symbol_table, depending on whether -n or -T were set. 5060Sstevel@tonic-gate */ 5070Sstevel@tonic-gate static void 5080Sstevel@tonic-gate print_symtab(Elf *elf_file, SCNTAB *p_symtab, Elf_Data *sym_data, 5090Sstevel@tonic-gate long range, int index) 5100Sstevel@tonic-gate { 5110Sstevel@tonic-gate GElf_Sym sym; 5120Sstevel@tonic-gate int adj = 0; /* field adjustment for elf64 */ 5130Sstevel@tonic-gate Elf32_Word *symshndx = 0; 5140Sstevel@tonic-gate unsigned int nosymshndx = 0; 5150Sstevel@tonic-gate 5160Sstevel@tonic-gate if (gelf_getclass(elf_file) == ELFCLASS64) 517*1618Srie adj = 8; 5180Sstevel@tonic-gate 5190Sstevel@tonic-gate while (range > 0) { 5200Sstevel@tonic-gate char *sym_name = (char *)0; 5210Sstevel@tonic-gate int type, bind; 5220Sstevel@tonic-gate int specsec; 5230Sstevel@tonic-gate unsigned int shndx; 5240Sstevel@tonic-gate 5250Sstevel@tonic-gate (void) gelf_getsym(sym_data, index, &sym); 5260Sstevel@tonic-gate type = (int)GELF_ST_TYPE(sym.st_info); 5270Sstevel@tonic-gate bind = (int)GELF_ST_BIND(sym.st_info); 5280Sstevel@tonic-gate 5290Sstevel@tonic-gate if ((sym.st_shndx == SHN_XINDEX) && 5300Sstevel@tonic-gate (symshndx == 0) && (nosymshndx == 0)) { 5310Sstevel@tonic-gate Elf_Scn *_scn; 5320Sstevel@tonic-gate GElf_Shdr _shdr; 5330Sstevel@tonic-gate size_t symscnndx; 5340Sstevel@tonic-gate 5350Sstevel@tonic-gate symscnndx = elf_ndxscn(p_symtab->p_sd); 5360Sstevel@tonic-gate _scn = 0; 5370Sstevel@tonic-gate while ((_scn = elf_nextscn(elf_file, _scn)) != 0) { 5380Sstevel@tonic-gate if (gelf_getshdr(_scn, &_shdr) == 0) 5390Sstevel@tonic-gate break; 5400Sstevel@tonic-gate if ((_shdr.sh_type == SHT_SYMTAB_SHNDX) && 5410Sstevel@tonic-gate /* LINTED */ 5420Sstevel@tonic-gate (_shdr.sh_link == (GElf_Word)symscnndx)) { 5430Sstevel@tonic-gate Elf_Data *_data; 5440Sstevel@tonic-gate 5450Sstevel@tonic-gate if ((_data = elf_getdata(_scn, 0)) == 0) 5460Sstevel@tonic-gate continue; 5470Sstevel@tonic-gate 5480Sstevel@tonic-gate symshndx = (Elf32_Word *)_data->d_buf; 5490Sstevel@tonic-gate nosymshndx = 0; 5500Sstevel@tonic-gate break; 5510Sstevel@tonic-gate } 5520Sstevel@tonic-gate } 5530Sstevel@tonic-gate nosymshndx = 1; 5540Sstevel@tonic-gate } 5550Sstevel@tonic-gate 5560Sstevel@tonic-gate if ((symshndx) && (sym.st_shndx == SHN_XINDEX)) { 5570Sstevel@tonic-gate shndx = symshndx[index]; 5580Sstevel@tonic-gate specsec = 0; 5590Sstevel@tonic-gate } else { 5600Sstevel@tonic-gate shndx = sym.st_shndx; 5610Sstevel@tonic-gate if ((sym.st_shndx == SHN_UNDEF) || 5620Sstevel@tonic-gate (sym.st_shndx >= SHN_LORESERVE)) 5630Sstevel@tonic-gate specsec = 1; 5640Sstevel@tonic-gate else 5650Sstevel@tonic-gate specsec = 0; 5660Sstevel@tonic-gate } 5670Sstevel@tonic-gate 5680Sstevel@tonic-gate 5690Sstevel@tonic-gate (void) printf("[%d]\t ", index++); 5700Sstevel@tonic-gate 5710Sstevel@tonic-gate if (v_flag && (type == STT_SPARC_REGISTER)) { 5720Sstevel@tonic-gate /* 5730Sstevel@tonic-gate * The strings "REG_G1" through "REG_G7" are intended 5740Sstevel@tonic-gate * to be consistent with output from elfdump(1). 5750Sstevel@tonic-gate */ 5760Sstevel@tonic-gate switch (sym.st_value) { 5770Sstevel@tonic-gate case STO_SPARC_REGISTER_G1: 5780Sstevel@tonic-gate (void) printf("%-*s", 12 + adj, "REG_G1"); 5790Sstevel@tonic-gate break; 5800Sstevel@tonic-gate case STO_SPARC_REGISTER_G2: 5810Sstevel@tonic-gate (void) printf("%-*s", 12 + adj, "REG_G2"); 5820Sstevel@tonic-gate break; 5830Sstevel@tonic-gate case STO_SPARC_REGISTER_G3: 5840Sstevel@tonic-gate (void) printf("%-*s", 12 + adj, "REG_G3"); 5850Sstevel@tonic-gate break; 5860Sstevel@tonic-gate case STO_SPARC_REGISTER_G4: 5870Sstevel@tonic-gate (void) printf("%-*s", 12 + adj, "REG_G4"); 5880Sstevel@tonic-gate break; 5890Sstevel@tonic-gate case STO_SPARC_REGISTER_G5: 5900Sstevel@tonic-gate (void) printf("%-*s", 12 + adj, "REG_G5"); 5910Sstevel@tonic-gate break; 5920Sstevel@tonic-gate case STO_SPARC_REGISTER_G6: 5930Sstevel@tonic-gate (void) printf("%-*s", 12 + adj, "REG_G6"); 5940Sstevel@tonic-gate break; 5950Sstevel@tonic-gate case STO_SPARC_REGISTER_G7: 5960Sstevel@tonic-gate (void) printf("%-*s", 12 + adj, "REG_G7"); 5970Sstevel@tonic-gate break; 5980Sstevel@tonic-gate default: 5990Sstevel@tonic-gate (void) printf("0x%-*llx", 10 + adj, 6000Sstevel@tonic-gate EC_ADDR(sym.st_value)); 6010Sstevel@tonic-gate } 6020Sstevel@tonic-gate } else 6030Sstevel@tonic-gate (void) printf("0x%-*llx", 10 + adj, 6040Sstevel@tonic-gate EC_ADDR(sym.st_value)); 6050Sstevel@tonic-gate 6060Sstevel@tonic-gate (void) printf("%-*lld", 9 + adj, EC_XWORD(sym.st_size)); 6070Sstevel@tonic-gate 6080Sstevel@tonic-gate if (!v_flag) { 6090Sstevel@tonic-gate (void) printf("%d\t\t%d\t%d\t%#x\t", 6100Sstevel@tonic-gate type, bind, (int)sym.st_other, (int)shndx); 6110Sstevel@tonic-gate } else { 6120Sstevel@tonic-gate switch (type) { 6130Sstevel@tonic-gate case STT_NOTYPE: 6140Sstevel@tonic-gate (void) printf("%s\t", "NOTY"); 6150Sstevel@tonic-gate break; 6160Sstevel@tonic-gate case STT_OBJECT: 6170Sstevel@tonic-gate (void) printf("%s\t", "OBJT"); 6180Sstevel@tonic-gate break; 6190Sstevel@tonic-gate case STT_FUNC: 6200Sstevel@tonic-gate (void) printf("%s\t", "FUNC"); 6210Sstevel@tonic-gate break; 6220Sstevel@tonic-gate case STT_SECTION: 6230Sstevel@tonic-gate (void) printf("%s\t", "SECT"); 6240Sstevel@tonic-gate break; 6250Sstevel@tonic-gate case STT_FILE: 6260Sstevel@tonic-gate (void) printf("%s\t", "FILE"); 6270Sstevel@tonic-gate break; 6280Sstevel@tonic-gate case STT_SPARC_REGISTER: 6290Sstevel@tonic-gate (void) printf("%s\t", "REGI"); 6300Sstevel@tonic-gate break; 6310Sstevel@tonic-gate case STT_COMMON: 6320Sstevel@tonic-gate (void) printf("%s\t", "COMM"); 6330Sstevel@tonic-gate break; 6340Sstevel@tonic-gate case STT_TLS: 6350Sstevel@tonic-gate (void) printf("%s\t", "TLS "); 6360Sstevel@tonic-gate break; 6370Sstevel@tonic-gate default: 6380Sstevel@tonic-gate (void) printf("%d\t", type); 6390Sstevel@tonic-gate } 6400Sstevel@tonic-gate switch (bind) { 6410Sstevel@tonic-gate case STB_LOCAL: 6420Sstevel@tonic-gate (void) printf("LOCL"); 6430Sstevel@tonic-gate break; 6440Sstevel@tonic-gate case STB_GLOBAL: 6450Sstevel@tonic-gate (void) printf("GLOB"); 6460Sstevel@tonic-gate break; 6470Sstevel@tonic-gate case STB_WEAK: 6480Sstevel@tonic-gate (void) printf("WEAK"); 6490Sstevel@tonic-gate break; 6500Sstevel@tonic-gate default: 6510Sstevel@tonic-gate (void) printf("%d", bind); 6520Sstevel@tonic-gate } 6530Sstevel@tonic-gate (void) printf("\t %d\t", EC_WORD(sym.st_other)); 6540Sstevel@tonic-gate 6550Sstevel@tonic-gate if (specsec) { 6560Sstevel@tonic-gate switch (shndx) { 6570Sstevel@tonic-gate case SHN_UNDEF: 6580Sstevel@tonic-gate (void) printf("UNDEF"); 6590Sstevel@tonic-gate break; 6600Sstevel@tonic-gate case SHN_ABS: 6610Sstevel@tonic-gate (void) printf("ABS"); 6620Sstevel@tonic-gate break; 6630Sstevel@tonic-gate case SHN_COMMON: 6640Sstevel@tonic-gate (void) printf("COMMON"); 6650Sstevel@tonic-gate break; 6660Sstevel@tonic-gate case SHN_XINDEX: 6670Sstevel@tonic-gate (void) printf("XINDEX"); 6680Sstevel@tonic-gate break; 6690Sstevel@tonic-gate default: 6700Sstevel@tonic-gate (void) printf("%d", EC_WORD(shndx)); 6710Sstevel@tonic-gate } 6720Sstevel@tonic-gate } else 6730Sstevel@tonic-gate (void) printf("%d", EC_WORD(shndx)); 6740Sstevel@tonic-gate (void) printf("\t"); 6750Sstevel@tonic-gate } 6760Sstevel@tonic-gate 6770Sstevel@tonic-gate /* support machines where NULL-deref causes core dump */ 6780Sstevel@tonic-gate if (sym.st_name == 0) 6790Sstevel@tonic-gate sym_name = (char *)UNKNOWN; 6800Sstevel@tonic-gate else 6810Sstevel@tonic-gate if (C_flag) 6820Sstevel@tonic-gate sym_name = demangled_name( 6830Sstevel@tonic-gate (char *)elf_strptr(elf_file, 6840Sstevel@tonic-gate p_symtab->p_shdr.sh_link, 6850Sstevel@tonic-gate sym.st_name)); 6860Sstevel@tonic-gate else 6870Sstevel@tonic-gate sym_name = (char *)elf_strptr(elf_file, 6880Sstevel@tonic-gate p_symtab->p_shdr.sh_link, 6890Sstevel@tonic-gate sym.st_name); 6900Sstevel@tonic-gate if (sym_name == NULL) 6910Sstevel@tonic-gate sym_name = (char *)UNKNOWN; 6920Sstevel@tonic-gate (void) printf("%s\n", sym_name); 6930Sstevel@tonic-gate 6940Sstevel@tonic-gate range--; 6950Sstevel@tonic-gate } /* end while */ 6960Sstevel@tonic-gate } 6970Sstevel@tonic-gate 6980Sstevel@tonic-gate /* 6990Sstevel@tonic-gate * Print the section header table. Input is the SCNTAB structure, 7000Sstevel@tonic-gate * the number of sections, an index which is the number of the 7010Sstevel@tonic-gate * section in the file, and the filename. The values of the SCNTAB 7020Sstevel@tonic-gate * structure, the number of sections, and the index are set in 7030Sstevel@tonic-gate * dump_shdr depending on whether the -n or -d modifiers were set. 7040Sstevel@tonic-gate */ 7050Sstevel@tonic-gate static void 7060Sstevel@tonic-gate print_shdr(Elf *elf_file, SCNTAB *s, int num_scns, int index) 7070Sstevel@tonic-gate { 7080Sstevel@tonic-gate SCNTAB *p; 7090Sstevel@tonic-gate int num; 7100Sstevel@tonic-gate int field; 7110Sstevel@tonic-gate 7120Sstevel@tonic-gate if (gelf_getclass(elf_file) == ELFCLASS64) 713*1618Srie field = 21; 7140Sstevel@tonic-gate else 7150Sstevel@tonic-gate field = 13; 7160Sstevel@tonic-gate 7170Sstevel@tonic-gate p = s; 7180Sstevel@tonic-gate 7190Sstevel@tonic-gate for (num = 0; num < num_scns; num++, p++) { 7200Sstevel@tonic-gate (void) printf("[%d]\t", index++); 7210Sstevel@tonic-gate if (!v_flag) { 7220Sstevel@tonic-gate (void) printf("%u\t%llu\t", 7230Sstevel@tonic-gate EC_WORD(p->p_shdr.sh_type), 7240Sstevel@tonic-gate EC_XWORD(p->p_shdr.sh_flags)); 7250Sstevel@tonic-gate } else { 7260Sstevel@tonic-gate switch (p->p_shdr.sh_type) { 7270Sstevel@tonic-gate case SHT_NULL: 7280Sstevel@tonic-gate (void) printf("NULL"); 7290Sstevel@tonic-gate break; 7300Sstevel@tonic-gate case SHT_PROGBITS: 7310Sstevel@tonic-gate (void) printf("PBIT"); 7320Sstevel@tonic-gate break; 7330Sstevel@tonic-gate case SHT_SYMTAB: 7340Sstevel@tonic-gate (void) printf("SYMT"); 7350Sstevel@tonic-gate break; 7360Sstevel@tonic-gate case SHT_STRTAB: 7370Sstevel@tonic-gate (void) printf("STRT"); 7380Sstevel@tonic-gate break; 7390Sstevel@tonic-gate case SHT_RELA: 7400Sstevel@tonic-gate (void) printf("RELA"); 7410Sstevel@tonic-gate break; 7420Sstevel@tonic-gate case SHT_HASH: 7430Sstevel@tonic-gate (void) printf("HASH"); 7440Sstevel@tonic-gate break; 7450Sstevel@tonic-gate case SHT_DYNAMIC: 7460Sstevel@tonic-gate (void) printf("DYNM"); 7470Sstevel@tonic-gate break; 7480Sstevel@tonic-gate case SHT_NOTE: 7490Sstevel@tonic-gate (void) printf("NOTE"); 7500Sstevel@tonic-gate break; 7510Sstevel@tonic-gate case SHT_NOBITS: 7520Sstevel@tonic-gate (void) printf("NOBI"); 7530Sstevel@tonic-gate break; 7540Sstevel@tonic-gate case SHT_REL: 7550Sstevel@tonic-gate (void) printf("REL "); 7560Sstevel@tonic-gate break; 7570Sstevel@tonic-gate case SHT_DYNSYM: 7580Sstevel@tonic-gate (void) printf("DYNS"); 7590Sstevel@tonic-gate break; 7600Sstevel@tonic-gate case ((GElf_Word) SHT_LOUSER): 7610Sstevel@tonic-gate (void) printf("LUSR"); 7620Sstevel@tonic-gate break; 7630Sstevel@tonic-gate case ((GElf_Word) SHT_HIUSER): 7640Sstevel@tonic-gate (void) printf("HUSR"); 7650Sstevel@tonic-gate break; 7660Sstevel@tonic-gate case SHT_SHLIB: 7670Sstevel@tonic-gate (void) printf("SHLB"); 7680Sstevel@tonic-gate break; 7690Sstevel@tonic-gate case SHT_SUNW_SIGNATURE: 7700Sstevel@tonic-gate (void) printf("SIGN"); 7710Sstevel@tonic-gate break; 7720Sstevel@tonic-gate case SHT_SUNW_ANNOTATE: 7730Sstevel@tonic-gate (void) printf("ANOT"); 7740Sstevel@tonic-gate break; 7750Sstevel@tonic-gate case SHT_SUNW_DEBUGSTR: 7760Sstevel@tonic-gate (void) printf("DBGS"); 7770Sstevel@tonic-gate break; 7780Sstevel@tonic-gate case SHT_SUNW_DEBUG: 7790Sstevel@tonic-gate (void) printf("DBG "); 7800Sstevel@tonic-gate break; 7810Sstevel@tonic-gate case SHT_SUNW_move: 7820Sstevel@tonic-gate (void) printf("MOVE"); 7830Sstevel@tonic-gate break; 7840Sstevel@tonic-gate case SHT_SUNW_verdef: 7850Sstevel@tonic-gate (void) printf("VERD"); 7860Sstevel@tonic-gate break; 7870Sstevel@tonic-gate case SHT_SUNW_verneed: 7880Sstevel@tonic-gate (void) printf("VERN"); 7890Sstevel@tonic-gate break; 7900Sstevel@tonic-gate case SHT_SUNW_versym: 7910Sstevel@tonic-gate (void) printf("VERS"); 7920Sstevel@tonic-gate break; 7930Sstevel@tonic-gate case SHT_SUNW_syminfo: 7940Sstevel@tonic-gate (void) printf("SYMI"); 7950Sstevel@tonic-gate break; 7960Sstevel@tonic-gate case SHT_SUNW_COMDAT: 7970Sstevel@tonic-gate (void) printf("COMD"); 7980Sstevel@tonic-gate break; 799*1618Srie case SHT_AMD64_UNWIND: 800*1618Srie (void) printf("UNWD"); 801*1618Srie break; 802*1618Srie case SHT_SPARC_GOTDATA: 803*1618Srie (void) printf("GOTD"); 804*1618Srie break; 8050Sstevel@tonic-gate default: 8060Sstevel@tonic-gate (void) printf("%u", EC_WORD(p->p_shdr.sh_type)); 8070Sstevel@tonic-gate break; 8080Sstevel@tonic-gate } 8090Sstevel@tonic-gate (void) printf(" "); 8100Sstevel@tonic-gate 8110Sstevel@tonic-gate if (p->p_shdr.sh_flags & SHF_WRITE) 8120Sstevel@tonic-gate (void) printf("W"); 8130Sstevel@tonic-gate else 8140Sstevel@tonic-gate (void) printf("-"); 8150Sstevel@tonic-gate if (p->p_shdr.sh_flags & SHF_ALLOC) 8160Sstevel@tonic-gate (void) printf("A"); 8170Sstevel@tonic-gate else 8180Sstevel@tonic-gate (void) printf("-"); 8190Sstevel@tonic-gate if (p->p_shdr.sh_flags & SHF_EXECINSTR) 8200Sstevel@tonic-gate (void) printf("I"); 8210Sstevel@tonic-gate else 8220Sstevel@tonic-gate (void) printf("-"); 8230Sstevel@tonic-gate 8240Sstevel@tonic-gate if (p->p_shdr.sh_flags & SHF_ORDERED) 8250Sstevel@tonic-gate (void) printf("O"); 8260Sstevel@tonic-gate if (p->p_shdr.sh_flags & SHF_EXCLUDE) 8270Sstevel@tonic-gate (void) printf("E"); 8280Sstevel@tonic-gate 8290Sstevel@tonic-gate (void) printf("\t"); 8300Sstevel@tonic-gate 8310Sstevel@tonic-gate } 8320Sstevel@tonic-gate (void) printf("%-#*llx%-#*llx%-#*llx%s%s\n", 8330Sstevel@tonic-gate field, EC_ADDR(p->p_shdr.sh_addr), 8340Sstevel@tonic-gate field, EC_OFF(p->p_shdr.sh_offset), 8350Sstevel@tonic-gate field, EC_XWORD(p->p_shdr.sh_size), 8360Sstevel@tonic-gate /* compatibility: tab for elf32 */ 8370Sstevel@tonic-gate (field == 13) ? "\t" : " ", p->scn_name); 8380Sstevel@tonic-gate 8390Sstevel@tonic-gate (void) printf("\t%u\t%u\t%-#*llx%-#*llx\n\n", 8400Sstevel@tonic-gate EC_WORD(p->p_shdr.sh_link), 8410Sstevel@tonic-gate EC_WORD(p->p_shdr.sh_info), 8420Sstevel@tonic-gate field, EC_XWORD(p->p_shdr.sh_addralign), 8430Sstevel@tonic-gate field, EC_XWORD(p->p_shdr.sh_entsize)); 8440Sstevel@tonic-gate } 8450Sstevel@tonic-gate } 8460Sstevel@tonic-gate 8470Sstevel@tonic-gate /* 8480Sstevel@tonic-gate * Check that a range of numbers is valid. Input is 8490Sstevel@tonic-gate * a lower bound, an upper bound, a boundary condition, 8500Sstevel@tonic-gate * and the filename. Negative numbers and numbers greater 8510Sstevel@tonic-gate * than the bound are invalid. low must be smaller than hi. 8520Sstevel@tonic-gate * The returned integer is the number of items in the 8530Sstevel@tonic-gate * range if it is valid and -1 otherwise. 8540Sstevel@tonic-gate */ 8550Sstevel@tonic-gate static int 8560Sstevel@tonic-gate check_range(int low, int hi, size_t bound, char *filename) 8570Sstevel@tonic-gate { 8580Sstevel@tonic-gate if (((size_t)low > bound) || (low <= 0)) { 8590Sstevel@tonic-gate (void) fprintf(stderr, 8600Sstevel@tonic-gate "%s: %s: number out of range, %d\n", 8610Sstevel@tonic-gate prog_name, filename, low); 8620Sstevel@tonic-gate return (-1); 8630Sstevel@tonic-gate } 8640Sstevel@tonic-gate if (((size_t)hi > bound) || (hi < 0)) { 8650Sstevel@tonic-gate (void) fprintf(stderr, 8660Sstevel@tonic-gate "%s: %s: number out of range, %d\n", 8670Sstevel@tonic-gate prog_name, filename, hi); 8680Sstevel@tonic-gate return (-1); 8690Sstevel@tonic-gate } 8700Sstevel@tonic-gate 8710Sstevel@tonic-gate if (hi && (low > hi)) { 8720Sstevel@tonic-gate (void) fprintf(stderr, 8730Sstevel@tonic-gate "%s: %s: invalid range, %d,%d\n", 8740Sstevel@tonic-gate prog_name, filename, low, hi); 8750Sstevel@tonic-gate return (-1); 8760Sstevel@tonic-gate } 8770Sstevel@tonic-gate if (hi) 8780Sstevel@tonic-gate return (hi - low + 1); 8790Sstevel@tonic-gate else 8800Sstevel@tonic-gate return (1); 8810Sstevel@tonic-gate } 8820Sstevel@tonic-gate 8830Sstevel@tonic-gate /* 8840Sstevel@tonic-gate * Print relocation information. Since this information is 8850Sstevel@tonic-gate * machine dependent, new sections must be added for each machine 8860Sstevel@tonic-gate * that is supported. Input is an ELF file descriptor, the ELF header, 8870Sstevel@tonic-gate * the SCNTAB structure, the number of sections, and a filename. 8880Sstevel@tonic-gate * Set up necessary information to print relocation information 8890Sstevel@tonic-gate * and call the appropriate print function depending on the 8900Sstevel@tonic-gate * type of relocation information. If the symbol table is 8910Sstevel@tonic-gate * absent, no relocation data is processed. Input is an 8920Sstevel@tonic-gate * ELF file descriptor, the ELF header, the SCNTAB structure, 8930Sstevel@tonic-gate * and the filename. Set range of d_flag and name if n_flag. 8940Sstevel@tonic-gate */ 8950Sstevel@tonic-gate static void 8960Sstevel@tonic-gate dump_reloc_table(Elf *elf_file, GElf_Ehdr *p_ehdr, 8970Sstevel@tonic-gate SCNTAB *p_scns, int num_scns, char *filename) 8980Sstevel@tonic-gate { 8990Sstevel@tonic-gate Elf_Data *rel_data; 9000Sstevel@tonic-gate Elf_Data *sym_data; 9010Sstevel@tonic-gate size_t sym_size; 9020Sstevel@tonic-gate size_t reloc_size; 9030Sstevel@tonic-gate SCNTAB *reloc_symtab; 9040Sstevel@tonic-gate SCNTAB *head_scns; 9050Sstevel@tonic-gate int r_title = 0; 9060Sstevel@tonic-gate int adj = 0; 9070Sstevel@tonic-gate size_t shnum; 9080Sstevel@tonic-gate 9090Sstevel@tonic-gate if (gelf_getclass(elf_file) == ELFCLASS64) 910*1618Srie adj = 8; 9110Sstevel@tonic-gate 9120Sstevel@tonic-gate if ((!p_flag) && (!r_title)) { 9130Sstevel@tonic-gate (void) printf("\n **** RELOCATION INFORMATION ****\n"); 9140Sstevel@tonic-gate r_title = 1; 9150Sstevel@tonic-gate } 9160Sstevel@tonic-gate 9170Sstevel@tonic-gate while (num_scns-- > 0) { 9180Sstevel@tonic-gate if ((p_scns->p_shdr.sh_type != SHT_RELA) && 9190Sstevel@tonic-gate (p_scns->p_shdr.sh_type != SHT_REL)) { 9200Sstevel@tonic-gate p_scns++; 9210Sstevel@tonic-gate continue; 9220Sstevel@tonic-gate } 9230Sstevel@tonic-gate 9240Sstevel@tonic-gate head_scns = p_head_scns; 9250Sstevel@tonic-gate 9260Sstevel@tonic-gate if (elf_getshnum(elf_file, &shnum) == 0) { 9270Sstevel@tonic-gate (void) fprintf(stderr, 9280Sstevel@tonic-gate "%s: %s: elf_getshnum failed: %s\n", 9290Sstevel@tonic-gate prog_name, filename, elf_errmsg(-1)); 9300Sstevel@tonic-gate return; 9310Sstevel@tonic-gate } 9320Sstevel@tonic-gate 9330Sstevel@tonic-gate if ((p_scns->p_shdr.sh_link == 0) || 9340Sstevel@tonic-gate /* LINTED */ 9350Sstevel@tonic-gate (p_scns->p_shdr.sh_link >= (GElf_Word)shnum)) { 9360Sstevel@tonic-gate (void) fprintf(stderr, "%s: %s: invalid sh_link field: " 9370Sstevel@tonic-gate "section #: %d sh_link: %d\n", 9380Sstevel@tonic-gate /* LINTED */ 9390Sstevel@tonic-gate prog_name, filename, (int)elf_ndxscn(p_scns->p_sd), 9400Sstevel@tonic-gate (int)p_scns->p_shdr.sh_link); 9410Sstevel@tonic-gate return; 9420Sstevel@tonic-gate } 9430Sstevel@tonic-gate head_scns += (p_scns->p_shdr.sh_link -1); 9440Sstevel@tonic-gate 9450Sstevel@tonic-gate if (head_scns->p_shdr.sh_type == SHT_SYMTAB) { 9460Sstevel@tonic-gate reloc_symtab = p_symtab; 9470Sstevel@tonic-gate } else if (head_scns->p_shdr.sh_type == SHT_DYNSYM) { 9480Sstevel@tonic-gate reloc_symtab = p_dynsym; 9490Sstevel@tonic-gate } else { 9500Sstevel@tonic-gate (void) fprintf(stderr, 9510Sstevel@tonic-gate "%s: %s: could not get symbol table\n", prog_name, filename); 9520Sstevel@tonic-gate return; 9530Sstevel@tonic-gate } 9540Sstevel@tonic-gate 9550Sstevel@tonic-gate sym_data = NULL; 9560Sstevel@tonic-gate sym_size = 0; 9570Sstevel@tonic-gate reloc_size = 0; 9580Sstevel@tonic-gate 9590Sstevel@tonic-gate if ((sym_data = elf_getdata(reloc_symtab->p_sd, NULL)) == NULL) { 9600Sstevel@tonic-gate (void) fprintf(stderr, 9610Sstevel@tonic-gate "%s: %s: no symbol table data\n", prog_name, filename); 9620Sstevel@tonic-gate return; 9630Sstevel@tonic-gate } 9640Sstevel@tonic-gate sym_size = sym_data->d_size; 9650Sstevel@tonic-gate 9660Sstevel@tonic-gate if (p_scns == NULL) { 9670Sstevel@tonic-gate (void) fprintf(stderr, 9680Sstevel@tonic-gate "%s: %s: no section table data\n", prog_name, filename); 9690Sstevel@tonic-gate return; 9700Sstevel@tonic-gate } 9710Sstevel@tonic-gate 9720Sstevel@tonic-gate if (p_scns->p_shdr.sh_type == SHT_RELA) { 9730Sstevel@tonic-gate if (!n_flag && r_flag) 9740Sstevel@tonic-gate (void) printf("\n%s:\n", p_scns->scn_name); 9750Sstevel@tonic-gate if (!p_flag && (!n_flag && r_flag)) 9760Sstevel@tonic-gate (void) printf("%-*s%-*s%-*s%s\n\n", 9770Sstevel@tonic-gate 12 + adj, "Offset", 22, "Symndx", 9780Sstevel@tonic-gate 18, "Type", "Addend"); 9790Sstevel@tonic-gate if ((rel_data = elf_getdata(p_scns->p_sd, NULL)) == NULL) { 9800Sstevel@tonic-gate (void) fprintf(stderr, 9810Sstevel@tonic-gate "%s: %s: no relocation information\n", prog_name, filename); 9820Sstevel@tonic-gate return; 9830Sstevel@tonic-gate } 9840Sstevel@tonic-gate reloc_size = rel_data->d_size; 9850Sstevel@tonic-gate 9860Sstevel@tonic-gate if (n_flag) { 9870Sstevel@tonic-gate rn_flag = 1; 9880Sstevel@tonic-gate print_rela(elf_file, p_scns, rel_data, sym_data, p_ehdr, 9890Sstevel@tonic-gate reloc_size, sym_size, filename, reloc_symtab); 9900Sstevel@tonic-gate } 9910Sstevel@tonic-gate if (d_flag) { 9920Sstevel@tonic-gate rn_flag = 0; 9930Sstevel@tonic-gate print_rela(elf_file, p_scns, rel_data, sym_data, p_ehdr, 9940Sstevel@tonic-gate reloc_size, sym_size, filename, reloc_symtab); 9950Sstevel@tonic-gate } 9960Sstevel@tonic-gate if (!n_flag && !d_flag) 9970Sstevel@tonic-gate print_rela(elf_file, p_scns, rel_data, sym_data, p_ehdr, 9980Sstevel@tonic-gate reloc_size, sym_size, filename, reloc_symtab); 9990Sstevel@tonic-gate } else { 10000Sstevel@tonic-gate if (p_scns->p_shdr.sh_type == SHT_REL) { 10010Sstevel@tonic-gate if (!n_flag && r_flag) 10020Sstevel@tonic-gate (void) printf("\n%s:\n", p_scns->scn_name); 10030Sstevel@tonic-gate if (!p_flag && (!n_flag && r_flag)) { 10040Sstevel@tonic-gate (void) printf("%-*s%-*s%s\n\n", 10050Sstevel@tonic-gate 12 + adj, "Offset", 20, "Symndx", "Type"); 10060Sstevel@tonic-gate } 10070Sstevel@tonic-gate if ((rel_data = elf_getdata(p_scns->p_sd, NULL)) 10080Sstevel@tonic-gate == NULL) { 10090Sstevel@tonic-gate (void) fprintf(stderr, 10100Sstevel@tonic-gate "%s: %s: no relocation information\n", prog_name, filename); 10110Sstevel@tonic-gate return; 10120Sstevel@tonic-gate } 10130Sstevel@tonic-gate reloc_size = rel_data->d_size; 10140Sstevel@tonic-gate if (n_flag) { 10150Sstevel@tonic-gate rn_flag = 1; 10160Sstevel@tonic-gate print_rel(elf_file, p_scns, rel_data, sym_data, 10170Sstevel@tonic-gate p_ehdr, reloc_size, sym_size, 10180Sstevel@tonic-gate filename, reloc_symtab); 10190Sstevel@tonic-gate } 10200Sstevel@tonic-gate if (d_flag) { 10210Sstevel@tonic-gate rn_flag = 0; 10220Sstevel@tonic-gate print_rel(elf_file, p_scns, rel_data, sym_data, 10230Sstevel@tonic-gate p_ehdr, reloc_size, sym_size, 10240Sstevel@tonic-gate filename, reloc_symtab); 10250Sstevel@tonic-gate } 10260Sstevel@tonic-gate if (!n_flag && !d_flag) 10270Sstevel@tonic-gate print_rel(elf_file, p_scns, rel_data, sym_data, 10280Sstevel@tonic-gate p_ehdr, reloc_size, sym_size, 10290Sstevel@tonic-gate filename, reloc_symtab); 10300Sstevel@tonic-gate } 10310Sstevel@tonic-gate } 10320Sstevel@tonic-gate p_scns++; 10330Sstevel@tonic-gate } 10340Sstevel@tonic-gate } 10350Sstevel@tonic-gate 10360Sstevel@tonic-gate /* 10370Sstevel@tonic-gate * Print out the string tables. Input is an opened ELF file, 10380Sstevel@tonic-gate * the SCNTAB structure, the number of sections, and the filename. 10390Sstevel@tonic-gate * Since there can be more than one string table, all sections are 10400Sstevel@tonic-gate * examined and any with the correct type are printed out. 10410Sstevel@tonic-gate */ 10420Sstevel@tonic-gate static void 10430Sstevel@tonic-gate dump_string_table(SCNTAB *s, int num_scns) 10440Sstevel@tonic-gate { 10450Sstevel@tonic-gate size_t section_size; 10460Sstevel@tonic-gate unsigned char *strtab; 10470Sstevel@tonic-gate int beg_of_string; 10480Sstevel@tonic-gate int counter = 0; 10490Sstevel@tonic-gate int str_off; 10500Sstevel@tonic-gate int i; 10510Sstevel@tonic-gate 10520Sstevel@tonic-gate if (!p_flag) { 10530Sstevel@tonic-gate (void) printf("\n **** STRING TABLE INFORMATION ****\n"); 10540Sstevel@tonic-gate } 10550Sstevel@tonic-gate 10560Sstevel@tonic-gate for (i = 0; i < num_scns; i++, s++) { 10570Sstevel@tonic-gate if (s->p_shdr.sh_type != SHT_STRTAB) 10580Sstevel@tonic-gate continue; 10590Sstevel@tonic-gate 10600Sstevel@tonic-gate str_off = 0; 10610Sstevel@tonic-gate 10620Sstevel@tonic-gate if (!p_flag) { 10630Sstevel@tonic-gate (void) printf("\n%s:\n", s->scn_name); 10640Sstevel@tonic-gate (void) printf(" <offset> \tName\n"); 10650Sstevel@tonic-gate } 10660Sstevel@tonic-gate section_size = 0; 10670Sstevel@tonic-gate if ((strtab = (unsigned char *) 10680Sstevel@tonic-gate get_scndata(s->p_sd, §ion_size)) == NULL) { 10690Sstevel@tonic-gate continue; 10700Sstevel@tonic-gate } 10710Sstevel@tonic-gate 10720Sstevel@tonic-gate if (section_size != 0) { 10730Sstevel@tonic-gate (void) printf(" <%d> \t", str_off); 10740Sstevel@tonic-gate beg_of_string = 0; 10750Sstevel@tonic-gate while (section_size--) { 10760Sstevel@tonic-gate unsigned char c = *strtab++; 10770Sstevel@tonic-gate 10780Sstevel@tonic-gate if (beg_of_string) { 10790Sstevel@tonic-gate (void) printf(" <%d> \t", str_off); 10800Sstevel@tonic-gate counter++; 10810Sstevel@tonic-gate beg_of_string = 0; 10820Sstevel@tonic-gate } 10830Sstevel@tonic-gate str_off++; 10840Sstevel@tonic-gate switch (c) { 10850Sstevel@tonic-gate case '\0': 10860Sstevel@tonic-gate (void) printf("\n"); 10870Sstevel@tonic-gate beg_of_string = 1; 10880Sstevel@tonic-gate break; 10890Sstevel@tonic-gate default: 10900Sstevel@tonic-gate (void) putchar(c); 10910Sstevel@tonic-gate } 10920Sstevel@tonic-gate } 10930Sstevel@tonic-gate } 10940Sstevel@tonic-gate } 10950Sstevel@tonic-gate (void) printf("\n"); 10960Sstevel@tonic-gate } 10970Sstevel@tonic-gate 10980Sstevel@tonic-gate /* 10990Sstevel@tonic-gate * Print the symbol table. This function does not print the contents 11000Sstevel@tonic-gate * of the symbol table but sets up the parameters and then calls 11010Sstevel@tonic-gate * print_symtab to print the symbols. Calling another function to print 11020Sstevel@tonic-gate * the symbols allows both -T and -n to work correctly 11030Sstevel@tonic-gate * simultaneously. Input is an opened ELF file, a pointer to the 11040Sstevel@tonic-gate * symbol table SCNTAB structure, and the filename. 11050Sstevel@tonic-gate * Set the range of symbols to print if T_flag, and set 11060Sstevel@tonic-gate * name of symbol to print if n_flag. 11070Sstevel@tonic-gate */ 11080Sstevel@tonic-gate static void 11090Sstevel@tonic-gate dump_symbol_table(Elf *elf_file, SCNTAB *p_symtab, char *filename) 11100Sstevel@tonic-gate { 11110Sstevel@tonic-gate Elf_Data *sym_data; 11120Sstevel@tonic-gate GElf_Sym T_range, n_range; /* for use with -T and -n */ 11130Sstevel@tonic-gate size_t count = 0; 11140Sstevel@tonic-gate size_t sym_size; 11150Sstevel@tonic-gate int index = 1; 11160Sstevel@tonic-gate int found_it = 0; 11170Sstevel@tonic-gate int i; 11180Sstevel@tonic-gate int adj = 0; /* field adjustment for elf64 */ 11190Sstevel@tonic-gate 11200Sstevel@tonic-gate if (gelf_getclass(elf_file) == ELFCLASS64) 1121*1618Srie adj = 8; 11220Sstevel@tonic-gate 11230Sstevel@tonic-gate if (p_symtab == NULL) { 11240Sstevel@tonic-gate (void) fprintf(stderr, 11250Sstevel@tonic-gate "%s: %s: could not get symbol table\n", prog_name, filename); 11260Sstevel@tonic-gate return; 11270Sstevel@tonic-gate } 11280Sstevel@tonic-gate 11290Sstevel@tonic-gate /* get symbol table data */ 11300Sstevel@tonic-gate sym_data = NULL; 11310Sstevel@tonic-gate sym_size = 0; 11320Sstevel@tonic-gate if ((sym_data = 11330Sstevel@tonic-gate elf_getdata(p_symtab->p_sd, NULL)) == NULL) { 11340Sstevel@tonic-gate (void) printf("\n%s:\n", p_symtab->scn_name); 11350Sstevel@tonic-gate (void) printf("No symbol table data\n"); 11360Sstevel@tonic-gate return; 11370Sstevel@tonic-gate } 11380Sstevel@tonic-gate sym_size = sym_data->d_size; 11390Sstevel@tonic-gate 11400Sstevel@tonic-gate count = sym_size / p_symtab->p_shdr.sh_entsize; 11410Sstevel@tonic-gate 11420Sstevel@tonic-gate if (n_flag && t_flag && !T_flag) { 11430Sstevel@tonic-gate /* LINTED */ 11440Sstevel@tonic-gate for (i = 1; i < count; i++) { 11450Sstevel@tonic-gate (void) gelf_getsym(sym_data, i, &n_range); 11460Sstevel@tonic-gate if (strcmp(name, (char *) 11470Sstevel@tonic-gate elf_strptr(elf_file, 11480Sstevel@tonic-gate p_symtab->p_shdr.sh_link, 11490Sstevel@tonic-gate n_range.st_name)) != 0) { 11500Sstevel@tonic-gate continue; 11510Sstevel@tonic-gate } else { 11520Sstevel@tonic-gate found_it = 1; 11530Sstevel@tonic-gate if (!p_flag) { 11540Sstevel@tonic-gate (void) printf( 11550Sstevel@tonic-gate "\n ***** SYMBOL TABLE INFORMATION *****\n"); 11560Sstevel@tonic-gate (void) printf( 11570Sstevel@tonic-gate "[Index] %-*s%-*sType\tBind\tOther\tShndx\tName", 11580Sstevel@tonic-gate 12 + adj, "Value", 9 + adj, "Size"); 11590Sstevel@tonic-gate } 11600Sstevel@tonic-gate (void) printf("\n%s:\n", p_symtab->scn_name); 11610Sstevel@tonic-gate print_symtab(elf_file, p_symtab, sym_data, 11620Sstevel@tonic-gate 1, i); 11630Sstevel@tonic-gate } 11640Sstevel@tonic-gate } /* end for */ 11650Sstevel@tonic-gate if (!found_it) { 11660Sstevel@tonic-gate (void) fprintf(stderr, "%s: %s: %s not found\n", 11670Sstevel@tonic-gate prog_name, filename, name); 11680Sstevel@tonic-gate } 11690Sstevel@tonic-gate } else if (T_flag) { 11700Sstevel@tonic-gate T_num = check_range(T_low, T_hi, count, filename); 11710Sstevel@tonic-gate if (T_num < 0) 11720Sstevel@tonic-gate return; 11730Sstevel@tonic-gate 11740Sstevel@tonic-gate (void) gelf_getsym(sym_data, T_low-1, &T_range); 11750Sstevel@tonic-gate index = T_low; 11760Sstevel@tonic-gate 11770Sstevel@tonic-gate if (!p_flag) { 11780Sstevel@tonic-gate (void) printf( 11790Sstevel@tonic-gate "\n ***** SYMBOL TABLE INFORMATION *****\n"); 11800Sstevel@tonic-gate (void) printf( 11810Sstevel@tonic-gate "[Index] %-*s%-*sType\tBind\tOther\tShndx\tName", 11820Sstevel@tonic-gate 12 + adj, "Value", 9 + adj, "Size"); 11830Sstevel@tonic-gate } 11840Sstevel@tonic-gate (void) printf("\n%s:\n", p_symtab->scn_name); 11850Sstevel@tonic-gate print_symtab(elf_file, p_symtab, sym_data, T_num, index); 11860Sstevel@tonic-gate } else { 11870Sstevel@tonic-gate if (!p_flag) { 11880Sstevel@tonic-gate (void) printf( 11890Sstevel@tonic-gate "\n ***** SYMBOL TABLE INFORMATION *****\n"); 11900Sstevel@tonic-gate (void) printf( 11910Sstevel@tonic-gate "[Index] %-*s%-*sType\tBind\tOther\tShndx\tName", 11920Sstevel@tonic-gate 12 + adj, "Value", 9 + adj, "Size"); 11930Sstevel@tonic-gate } 11940Sstevel@tonic-gate (void) printf("\n%s:\n", p_symtab->scn_name); 11950Sstevel@tonic-gate print_symtab(elf_file, p_symtab, sym_data, count-1, 1); 11960Sstevel@tonic-gate } 11970Sstevel@tonic-gate } 11980Sstevel@tonic-gate 11990Sstevel@tonic-gate /* 12000Sstevel@tonic-gate * Print dynamic linking information. Input is an ELF 12010Sstevel@tonic-gate * file descriptor, the SCNTAB structure, the number of 12020Sstevel@tonic-gate * sections, and the filename. 12030Sstevel@tonic-gate */ 12040Sstevel@tonic-gate static void 12050Sstevel@tonic-gate dump_dynamic(Elf *elf_file, SCNTAB *p_scns, int num_scns, char *filename) 12060Sstevel@tonic-gate { 12070Sstevel@tonic-gate Elf_Data *dyn_data; 12080Sstevel@tonic-gate GElf_Dyn p_dyn; 12090Sstevel@tonic-gate GElf_Phdr p_phdr; 12100Sstevel@tonic-gate GElf_Ehdr p_ehdr; 12110Sstevel@tonic-gate char *dt_name; 12120Sstevel@tonic-gate int index = 1; 12130Sstevel@tonic-gate int lib_scns = num_scns; 12140Sstevel@tonic-gate SCNTAB *l_scns = p_scns; 12150Sstevel@tonic-gate int header_num = 0; 12160Sstevel@tonic-gate #define Fmttag "%-15.15s " 12170Sstevel@tonic-gate #define Fmtptr "%#llx" 12180Sstevel@tonic-gate 12190Sstevel@tonic-gate if (!p_flag) 12200Sstevel@tonic-gate (void) printf("\n **** DYNAMIC SECTION INFORMATION ****\n"); 12210Sstevel@tonic-gate 12220Sstevel@tonic-gate for (; num_scns > 0; num_scns--, p_scns++) { 12230Sstevel@tonic-gate GElf_Word link; 12240Sstevel@tonic-gate int ii; 12250Sstevel@tonic-gate 12260Sstevel@tonic-gate 12270Sstevel@tonic-gate if (p_scns->p_shdr.sh_type != SHT_DYNAMIC) 12280Sstevel@tonic-gate continue; 12290Sstevel@tonic-gate 12300Sstevel@tonic-gate if (!p_flag) { 12310Sstevel@tonic-gate (void) printf("%s:\n", p_scns->scn_name); 12320Sstevel@tonic-gate (void) printf("[INDEX]\tTag Value\n"); 12330Sstevel@tonic-gate } 12340Sstevel@tonic-gate 12350Sstevel@tonic-gate if ((dyn_data = elf_getdata(p_scns->p_sd, NULL)) == 0) { 12360Sstevel@tonic-gate (void) fprintf(stderr, "%s: %s: no data in " 12370Sstevel@tonic-gate "%s section\n", prog_name, filename, 12380Sstevel@tonic-gate p_scns->scn_name); 12390Sstevel@tonic-gate return; 12400Sstevel@tonic-gate } 12410Sstevel@tonic-gate 12420Sstevel@tonic-gate link = p_scns->p_shdr.sh_link; 12430Sstevel@tonic-gate ii = 0; 12440Sstevel@tonic-gate 12450Sstevel@tonic-gate (void) gelf_getdyn(dyn_data, ii++, &p_dyn); 12460Sstevel@tonic-gate while (p_dyn.d_tag != DT_NULL) { 12470Sstevel@tonic-gate char value[256]; 12480Sstevel@tonic-gate 12490Sstevel@tonic-gate (void) printf("[%d]\t", index++); 12500Sstevel@tonic-gate 12510Sstevel@tonic-gate switch (p_dyn.d_tag) { 12520Sstevel@tonic-gate /* 12530Sstevel@tonic-gate * Start of generic flags. 12540Sstevel@tonic-gate */ 12550Sstevel@tonic-gate case (DT_NEEDED): 12560Sstevel@tonic-gate (void) printf(Fmttag, (const char *)"NEEDED"); 12570Sstevel@tonic-gate if (v_flag) 12580Sstevel@tonic-gate dt_name = (char *)elf_strptr(elf_file, 12590Sstevel@tonic-gate link, p_dyn.d_un.d_ptr); 12600Sstevel@tonic-gate if (dt_name == NULL) 12610Sstevel@tonic-gate dt_name = (char *)UNKNOWN; 12620Sstevel@tonic-gate if (v_flag && strlen(dt_name)) 12630Sstevel@tonic-gate (void) printf("%s", dt_name); 12640Sstevel@tonic-gate else 12650Sstevel@tonic-gate (void) printf(Fmtptr, 12660Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_ptr)); 12670Sstevel@tonic-gate break; 12680Sstevel@tonic-gate case (DT_PLTRELSZ): 12690Sstevel@tonic-gate (void) printf(Fmttag, (const char *)"PLTSZ"); 12700Sstevel@tonic-gate (void) printf(Fmtptr, 12710Sstevel@tonic-gate EC_XWORD(p_dyn.d_un.d_val)); 12720Sstevel@tonic-gate break; 12730Sstevel@tonic-gate case (DT_PLTGOT): 12740Sstevel@tonic-gate (void) printf(Fmttag, (const char *)"PLTGOT"); 12750Sstevel@tonic-gate (void) printf(Fmtptr, 12760Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_ptr)); 12770Sstevel@tonic-gate break; 12780Sstevel@tonic-gate case (DT_HASH): 12790Sstevel@tonic-gate (void) printf(Fmttag, (const char *)"HASH"); 12800Sstevel@tonic-gate (void) printf(Fmtptr, 12810Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_ptr)); 12820Sstevel@tonic-gate break; 12830Sstevel@tonic-gate case (DT_STRTAB): 12840Sstevel@tonic-gate (void) printf(Fmttag, (const char *)"STRTAB"); 12850Sstevel@tonic-gate (void) printf(Fmtptr, 12860Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_ptr)); 12870Sstevel@tonic-gate break; 12880Sstevel@tonic-gate case (DT_SYMTAB): 12890Sstevel@tonic-gate (void) printf(Fmttag, (const char *)"SYMTAB"); 12900Sstevel@tonic-gate (void) printf(Fmtptr, 12910Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_ptr)); 12920Sstevel@tonic-gate break; 12930Sstevel@tonic-gate case (DT_RELA): 12940Sstevel@tonic-gate (void) printf(Fmttag, (const char *)"RELA"); 12950Sstevel@tonic-gate (void) printf(Fmtptr, 12960Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_ptr)); 12970Sstevel@tonic-gate break; 12980Sstevel@tonic-gate case (DT_RELASZ): 12990Sstevel@tonic-gate (void) printf(Fmttag, (const char *)"RELASZ"); 13000Sstevel@tonic-gate (void) printf(Fmtptr, 13010Sstevel@tonic-gate EC_XWORD(p_dyn.d_un.d_val)); 13020Sstevel@tonic-gate break; 13030Sstevel@tonic-gate case (DT_RELAENT): 13040Sstevel@tonic-gate (void) printf(Fmttag, (const char *)"RELAENT"); 13050Sstevel@tonic-gate (void) printf(Fmtptr, 13060Sstevel@tonic-gate EC_XWORD(p_dyn.d_un.d_val)); 13070Sstevel@tonic-gate break; 13080Sstevel@tonic-gate case (DT_STRSZ): 13090Sstevel@tonic-gate (void) printf(Fmttag, (const char *)"STRSZ"); 13100Sstevel@tonic-gate (void) printf(Fmtptr, 13110Sstevel@tonic-gate EC_XWORD(p_dyn.d_un.d_val)); 13120Sstevel@tonic-gate break; 13130Sstevel@tonic-gate case (DT_SYMENT): 13140Sstevel@tonic-gate (void) printf(Fmttag, (const char *)"SYMENT"); 13150Sstevel@tonic-gate (void) printf(Fmtptr, 13160Sstevel@tonic-gate EC_XWORD(p_dyn.d_un.d_val)); 13170Sstevel@tonic-gate break; 13180Sstevel@tonic-gate case (DT_INIT): 13190Sstevel@tonic-gate (void) printf(Fmttag, (const char *)"INIT"); 13200Sstevel@tonic-gate (void) printf(Fmtptr, 13210Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_ptr)); 13220Sstevel@tonic-gate break; 13230Sstevel@tonic-gate case (DT_FINI): 13240Sstevel@tonic-gate (void) printf(Fmttag, (const char *)"FINI"); 13250Sstevel@tonic-gate (void) printf(Fmtptr, 13260Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_ptr)); 13270Sstevel@tonic-gate break; 13280Sstevel@tonic-gate case (DT_SONAME): 13290Sstevel@tonic-gate (void) printf(Fmttag, (const char *)"SONAME"); 13300Sstevel@tonic-gate if (v_flag) 13310Sstevel@tonic-gate dt_name = (char *)elf_strptr(elf_file, 13320Sstevel@tonic-gate link, p_dyn.d_un.d_ptr); 13330Sstevel@tonic-gate if (dt_name == NULL) 13340Sstevel@tonic-gate dt_name = (char *)UNKNOWN; 13350Sstevel@tonic-gate if (v_flag && strlen(dt_name)) 13360Sstevel@tonic-gate (void) printf("%s", dt_name); 13370Sstevel@tonic-gate else 13380Sstevel@tonic-gate (void) printf(Fmtptr, 13390Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_ptr)); 13400Sstevel@tonic-gate break; 13410Sstevel@tonic-gate case (DT_RPATH): 13420Sstevel@tonic-gate (void) printf(Fmttag, (const char *)"RPATH"); 13430Sstevel@tonic-gate if (v_flag) 13440Sstevel@tonic-gate dt_name = (char *)elf_strptr(elf_file, 13450Sstevel@tonic-gate link, p_dyn.d_un.d_ptr); 13460Sstevel@tonic-gate if (dt_name == NULL) 13470Sstevel@tonic-gate dt_name = (char *)UNKNOWN; 13480Sstevel@tonic-gate if (v_flag && strlen(dt_name)) 13490Sstevel@tonic-gate (void) printf("%s", dt_name); 13500Sstevel@tonic-gate else 13510Sstevel@tonic-gate (void) printf(Fmtptr, 13520Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_ptr)); 13530Sstevel@tonic-gate break; 13540Sstevel@tonic-gate case (DT_SYMBOLIC): 13550Sstevel@tonic-gate (void) printf(Fmttag, (const char *)"SYMB"); 13560Sstevel@tonic-gate (void) printf("%s", (const char *)"(ignored)"); 13570Sstevel@tonic-gate break; 13580Sstevel@tonic-gate case (DT_REL): 13590Sstevel@tonic-gate (void) printf(Fmttag, (const char *)"REL"); 13600Sstevel@tonic-gate (void) printf(Fmtptr, 13610Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_ptr)); 13620Sstevel@tonic-gate break; 13630Sstevel@tonic-gate case (DT_RELSZ): 13640Sstevel@tonic-gate (void) printf(Fmttag, (const char *)"RELSZ"); 13650Sstevel@tonic-gate (void) printf(Fmtptr, 13660Sstevel@tonic-gate EC_XWORD(p_dyn.d_un.d_val)); 13670Sstevel@tonic-gate break; 13680Sstevel@tonic-gate case (DT_RELENT): 13690Sstevel@tonic-gate (void) printf(Fmttag, (const char *)"RELENT"); 13700Sstevel@tonic-gate (void) printf(Fmtptr, 13710Sstevel@tonic-gate EC_XWORD(p_dyn.d_un.d_val)); 13720Sstevel@tonic-gate break; 13730Sstevel@tonic-gate case (DT_PLTREL): 13740Sstevel@tonic-gate (void) printf(Fmttag, (const char *)"PLTREL"); 13750Sstevel@tonic-gate (void) printf(Fmtptr, 13760Sstevel@tonic-gate EC_XWORD(p_dyn.d_un.d_val)); 13770Sstevel@tonic-gate break; 13780Sstevel@tonic-gate case (DT_DEBUG): 13790Sstevel@tonic-gate (void) printf(Fmttag, (const char *)"DEBUG"); 13800Sstevel@tonic-gate (void) printf(Fmtptr, 13810Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_ptr)); 13820Sstevel@tonic-gate break; 13830Sstevel@tonic-gate case (DT_TEXTREL): 13840Sstevel@tonic-gate (void) printf(Fmttag, (const char *)"TEXTREL"); 13850Sstevel@tonic-gate (void) printf(Fmtptr, 13860Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_val)); 13870Sstevel@tonic-gate break; 13880Sstevel@tonic-gate case (DT_JMPREL): 13890Sstevel@tonic-gate (void) printf(Fmttag, (const char *)"JMPREL"); 13900Sstevel@tonic-gate (void) printf(Fmtptr, 13910Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_ptr)); 13920Sstevel@tonic-gate break; 13930Sstevel@tonic-gate case (DT_BIND_NOW): 13940Sstevel@tonic-gate (void) printf(Fmttag, (const char *)"BIND_NOW"); 13950Sstevel@tonic-gate (void) printf(Fmtptr, 13960Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_val)); 13970Sstevel@tonic-gate break; 13980Sstevel@tonic-gate case (DT_INIT_ARRAY): 13990Sstevel@tonic-gate (void) printf(Fmttag, 14000Sstevel@tonic-gate (const char *)"INIT_ARRAY"); 14010Sstevel@tonic-gate (void) printf(Fmtptr, 14020Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_ptr)); 14030Sstevel@tonic-gate break; 14040Sstevel@tonic-gate case (DT_FINI_ARRAY): 14050Sstevel@tonic-gate (void) printf(Fmttag, 14060Sstevel@tonic-gate (const char *)"FINI_ARRAY"); 14070Sstevel@tonic-gate (void) printf(Fmtptr, 14080Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_ptr)); 14090Sstevel@tonic-gate break; 14100Sstevel@tonic-gate case (DT_INIT_ARRAYSZ): 14110Sstevel@tonic-gate (void) printf(Fmttag, 14120Sstevel@tonic-gate (const char *)"INIT_ARRAYSZ"); 14130Sstevel@tonic-gate (void) printf(Fmtptr, 14140Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_ptr)); 14150Sstevel@tonic-gate break; 14160Sstevel@tonic-gate case (DT_FINI_ARRAYSZ): 14170Sstevel@tonic-gate (void) printf(Fmttag, 14180Sstevel@tonic-gate (const char *)"FINI_ARRAYSZ"); 14190Sstevel@tonic-gate (void) printf(Fmtptr, 14200Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_ptr)); 14210Sstevel@tonic-gate break; 14220Sstevel@tonic-gate case (DT_RUNPATH): 14230Sstevel@tonic-gate (void) printf(Fmttag, (const char *)"RUNPATH"); 14240Sstevel@tonic-gate if (v_flag) 14250Sstevel@tonic-gate dt_name = (char *)elf_strptr(elf_file, 14260Sstevel@tonic-gate link, p_dyn.d_un.d_ptr); 14270Sstevel@tonic-gate if (dt_name == NULL) 14280Sstevel@tonic-gate dt_name = (char *)UNKNOWN; 14290Sstevel@tonic-gate if (v_flag && strlen(dt_name)) 14300Sstevel@tonic-gate (void) printf("%s", dt_name); 14310Sstevel@tonic-gate else 14320Sstevel@tonic-gate (void) printf(Fmtptr, 14330Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_ptr)); 14340Sstevel@tonic-gate break; 14350Sstevel@tonic-gate case (DT_FLAGS): 14360Sstevel@tonic-gate (void) printf(Fmttag, 14370Sstevel@tonic-gate (const char *)"FLAGS"); 14380Sstevel@tonic-gate value[0] = '\0'; 14390Sstevel@tonic-gate if (v_flag) { 14400Sstevel@tonic-gate if (p_dyn.d_un.d_val & DF_ORIGIN) 14410Sstevel@tonic-gate (void) strcat(value, 14420Sstevel@tonic-gate (const char *)"ORIGIN "); 14430Sstevel@tonic-gate if (p_dyn.d_un.d_val & DF_SYMBOLIC) 14440Sstevel@tonic-gate (void) strcat(value, 14450Sstevel@tonic-gate (const char *)"SYMBOLIC "); 14460Sstevel@tonic-gate if (p_dyn.d_un.d_val & DF_TEXTREL) 14470Sstevel@tonic-gate (void) strcat(value, 14480Sstevel@tonic-gate (const char *)"TEXTREL "); 14490Sstevel@tonic-gate if (p_dyn.d_un.d_val & DF_BIND_NOW) 14500Sstevel@tonic-gate (void) strcat(value, 14510Sstevel@tonic-gate (const char *)"BIND_NOW "); 14520Sstevel@tonic-gate if (p_dyn.d_un.d_val & DF_STATIC_TLS) 14530Sstevel@tonic-gate (void) strcat(value, 14540Sstevel@tonic-gate (const char *)"STATIC_TLS "); 14550Sstevel@tonic-gate } 14560Sstevel@tonic-gate if (v_flag && strlen(value)) 14570Sstevel@tonic-gate (void) printf("%s", value); 14580Sstevel@tonic-gate else 14590Sstevel@tonic-gate (void) printf(Fmtptr, 14600Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_ptr)); 14610Sstevel@tonic-gate break; 14620Sstevel@tonic-gate case (DT_PREINIT_ARRAY): 14630Sstevel@tonic-gate (void) printf(Fmttag, 14640Sstevel@tonic-gate (const char *)"PRINIT_ARRAY"); 14650Sstevel@tonic-gate (void) printf(Fmtptr, 14660Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_ptr)); 14670Sstevel@tonic-gate break; 14680Sstevel@tonic-gate case (DT_PREINIT_ARRAYSZ): 14690Sstevel@tonic-gate (void) printf(Fmttag, 14700Sstevel@tonic-gate (const char *)"PRINIT_ARRAYSZ"); 14710Sstevel@tonic-gate (void) printf(Fmtptr, 14720Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_ptr)); 14730Sstevel@tonic-gate break; 14740Sstevel@tonic-gate /* 14750Sstevel@tonic-gate * DT_LOOS - DT_HIOS range. 14760Sstevel@tonic-gate */ 14770Sstevel@tonic-gate case (DT_SUNW_AUXILIARY): 14780Sstevel@tonic-gate (void) printf(Fmttag, 14790Sstevel@tonic-gate (const char *)"SUNW_AUXILIARY"); 14800Sstevel@tonic-gate if (v_flag) 14810Sstevel@tonic-gate dt_name = (char *)elf_strptr(elf_file, 14820Sstevel@tonic-gate link, p_dyn.d_un.d_ptr); 14830Sstevel@tonic-gate if (dt_name == NULL) 14840Sstevel@tonic-gate dt_name = (char *)UNKNOWN; 14850Sstevel@tonic-gate if (v_flag && strlen(dt_name)) 14860Sstevel@tonic-gate (void) printf("%s", dt_name); 14870Sstevel@tonic-gate else 14880Sstevel@tonic-gate (void) printf(Fmtptr, 14890Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_ptr)); 14900Sstevel@tonic-gate break; 14910Sstevel@tonic-gate case (DT_SUNW_RTLDINF): 14920Sstevel@tonic-gate (void) printf(Fmttag, 14930Sstevel@tonic-gate (const char *)"SUNW_RTLDINF"); 14940Sstevel@tonic-gate (void) printf(Fmtptr, 14950Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_ptr)); 14960Sstevel@tonic-gate break; 14970Sstevel@tonic-gate case (DT_SUNW_FILTER): 14980Sstevel@tonic-gate (void) printf(Fmttag, 14990Sstevel@tonic-gate (const char *)"SUNW_FILTER"); 15000Sstevel@tonic-gate if (v_flag) 15010Sstevel@tonic-gate dt_name = (char *)elf_strptr(elf_file, 15020Sstevel@tonic-gate link, p_dyn.d_un.d_ptr); 15030Sstevel@tonic-gate if (dt_name == NULL) 15040Sstevel@tonic-gate dt_name = (char *)UNKNOWN; 15050Sstevel@tonic-gate if (v_flag && strlen(dt_name)) 15060Sstevel@tonic-gate (void) printf("%s", dt_name); 15070Sstevel@tonic-gate else 15080Sstevel@tonic-gate (void) printf(Fmtptr, 15090Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_ptr)); 15100Sstevel@tonic-gate break; 15110Sstevel@tonic-gate case (DT_SUNW_CAP): 15120Sstevel@tonic-gate (void) printf(Fmttag, 15130Sstevel@tonic-gate (const char *)"SUNW_CAP"); 15140Sstevel@tonic-gate (void) printf(Fmtptr, 15150Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_ptr)); 15160Sstevel@tonic-gate break; 15170Sstevel@tonic-gate 15180Sstevel@tonic-gate /* 15190Sstevel@tonic-gate * SUNW: DT_VALRNGLO - DT_VALRNGHI range. 15200Sstevel@tonic-gate */ 15210Sstevel@tonic-gate case (DT_CHECKSUM): 15220Sstevel@tonic-gate (void) printf(Fmttag, 15230Sstevel@tonic-gate (const char *)"CHECKSUM"); 15240Sstevel@tonic-gate (void) printf(Fmtptr, 15250Sstevel@tonic-gate EC_XWORD(p_dyn.d_un.d_val)); 15260Sstevel@tonic-gate break; 15270Sstevel@tonic-gate case (DT_PLTPADSZ): 15280Sstevel@tonic-gate (void) printf(Fmttag, 15290Sstevel@tonic-gate (const char *)"PLTPADSZ"); 15300Sstevel@tonic-gate (void) printf(Fmtptr, 15310Sstevel@tonic-gate EC_XWORD(p_dyn.d_un.d_val)); 15320Sstevel@tonic-gate break; 15330Sstevel@tonic-gate case (DT_MOVEENT): 15340Sstevel@tonic-gate (void) printf(Fmttag, 15350Sstevel@tonic-gate (const char *)"MOVEENT"); 15360Sstevel@tonic-gate (void) printf(Fmtptr, 15370Sstevel@tonic-gate EC_XWORD(p_dyn.d_un.d_val)); 15380Sstevel@tonic-gate break; 15390Sstevel@tonic-gate case (DT_MOVESZ): 15400Sstevel@tonic-gate (void) printf(Fmttag, 15410Sstevel@tonic-gate (const char *)"MOVESZ"); 15420Sstevel@tonic-gate (void) printf(Fmtptr, 15430Sstevel@tonic-gate EC_XWORD(p_dyn.d_un.d_val)); 15440Sstevel@tonic-gate break; 15450Sstevel@tonic-gate case (DT_FEATURE_1): 15460Sstevel@tonic-gate (void) printf(Fmttag, 15470Sstevel@tonic-gate (const char *)"FEATURE_1"); 15480Sstevel@tonic-gate value[0] = '\0'; 15490Sstevel@tonic-gate if (v_flag) { 15500Sstevel@tonic-gate if (p_dyn.d_un.d_val & DTF_1_PARINIT) 15510Sstevel@tonic-gate (void) strcat(value, 15520Sstevel@tonic-gate (const char *)"PARINIT "); 15530Sstevel@tonic-gate if (p_dyn.d_un.d_val & DTF_1_CONFEXP) 15540Sstevel@tonic-gate (void) strcat(value, 15550Sstevel@tonic-gate (const char *)"CONFEXP "); 15560Sstevel@tonic-gate } 15570Sstevel@tonic-gate if (v_flag && strlen(value)) 15580Sstevel@tonic-gate (void) printf("%s", value); 15590Sstevel@tonic-gate else 15600Sstevel@tonic-gate (void) printf(Fmtptr, 15610Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_ptr)); 15620Sstevel@tonic-gate break; 15630Sstevel@tonic-gate case (DT_POSFLAG_1): 15640Sstevel@tonic-gate (void) printf(Fmttag, 15650Sstevel@tonic-gate (const char *)"POSFLAG_1"); 15660Sstevel@tonic-gate value[0] = '\0'; 15670Sstevel@tonic-gate if (v_flag) { 15680Sstevel@tonic-gate if (p_dyn.d_un.d_val & DF_P1_LAZYLOAD) 15690Sstevel@tonic-gate (void) strcat(value, 15700Sstevel@tonic-gate (const char *)"LAZYLOAD "); 15710Sstevel@tonic-gate if (p_dyn.d_un.d_val & DF_P1_GROUPPERM) 15720Sstevel@tonic-gate (void) strcat(value, 15730Sstevel@tonic-gate (const char *)"GROUPPERM "); 15740Sstevel@tonic-gate } 15750Sstevel@tonic-gate if (v_flag && strlen(value)) 15760Sstevel@tonic-gate (void) printf("%s", value); 15770Sstevel@tonic-gate else 15780Sstevel@tonic-gate (void) printf(Fmtptr, 15790Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_ptr)); 15800Sstevel@tonic-gate break; 15810Sstevel@tonic-gate case (DT_SYMINSZ): 15820Sstevel@tonic-gate (void) printf(Fmttag, 15830Sstevel@tonic-gate (const char *)"SYMINSZ"); 15840Sstevel@tonic-gate (void) printf(Fmtptr, 15850Sstevel@tonic-gate EC_XWORD(p_dyn.d_un.d_val)); 15860Sstevel@tonic-gate break; 15870Sstevel@tonic-gate case (DT_SYMINENT): 15880Sstevel@tonic-gate (void) printf(Fmttag, 15890Sstevel@tonic-gate (const char *)"SYMINENT"); 15900Sstevel@tonic-gate (void) printf(Fmtptr, 15910Sstevel@tonic-gate EC_XWORD(p_dyn.d_un.d_val)); 15920Sstevel@tonic-gate break; 15930Sstevel@tonic-gate 15940Sstevel@tonic-gate /* 15950Sstevel@tonic-gate * SUNW: DT_ADDRRNGLO - DT_ADDRRNGHI range. 15960Sstevel@tonic-gate */ 15970Sstevel@tonic-gate case (DT_CONFIG): 15980Sstevel@tonic-gate (void) printf(Fmttag, (const char *)"CONFIG"); 15990Sstevel@tonic-gate if (v_flag) 16000Sstevel@tonic-gate dt_name = (char *)elf_strptr(elf_file, 16010Sstevel@tonic-gate link, p_dyn.d_un.d_ptr); 16020Sstevel@tonic-gate if (dt_name == NULL) 16030Sstevel@tonic-gate dt_name = (char *)UNKNOWN; 16040Sstevel@tonic-gate if (v_flag && strlen(dt_name)) 16050Sstevel@tonic-gate (void) printf("%s", dt_name); 16060Sstevel@tonic-gate else 16070Sstevel@tonic-gate (void) printf(Fmtptr, 16080Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_ptr)); 16090Sstevel@tonic-gate break; 16100Sstevel@tonic-gate case (DT_DEPAUDIT): 16110Sstevel@tonic-gate (void) printf(Fmttag, 16120Sstevel@tonic-gate (const char *)"DEPAUDIT"); 16130Sstevel@tonic-gate if (v_flag) 16140Sstevel@tonic-gate dt_name = (char *)elf_strptr(elf_file, 16150Sstevel@tonic-gate link, p_dyn.d_un.d_ptr); 16160Sstevel@tonic-gate if (dt_name == NULL) 16170Sstevel@tonic-gate dt_name = (char *)UNKNOWN; 16180Sstevel@tonic-gate if (v_flag && strlen(dt_name)) 16190Sstevel@tonic-gate (void) printf("%s", dt_name); 16200Sstevel@tonic-gate else 16210Sstevel@tonic-gate (void) printf(Fmtptr, 16220Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_ptr)); 16230Sstevel@tonic-gate break; 16240Sstevel@tonic-gate case (DT_AUDIT): 16250Sstevel@tonic-gate (void) printf(Fmttag, 16260Sstevel@tonic-gate (const char *)"AUDIT"); 16270Sstevel@tonic-gate if (v_flag) 16280Sstevel@tonic-gate dt_name = (char *)elf_strptr(elf_file, 16290Sstevel@tonic-gate link, p_dyn.d_un.d_ptr); 16300Sstevel@tonic-gate if (dt_name == NULL) 16310Sstevel@tonic-gate dt_name = (char *)UNKNOWN; 16320Sstevel@tonic-gate if (v_flag && strlen(dt_name)) 16330Sstevel@tonic-gate (void) printf("%s", dt_name); 16340Sstevel@tonic-gate else 16350Sstevel@tonic-gate (void) printf(Fmtptr, 16360Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_ptr)); 16370Sstevel@tonic-gate break; 16380Sstevel@tonic-gate case (DT_PLTPAD): 16390Sstevel@tonic-gate (void) printf(Fmttag, 16400Sstevel@tonic-gate (const char *)"PLTPAD"); 16410Sstevel@tonic-gate (void) printf(Fmtptr, 16420Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_ptr)); 16430Sstevel@tonic-gate break; 16440Sstevel@tonic-gate case (DT_MOVETAB): 16450Sstevel@tonic-gate (void) printf(Fmttag, 16460Sstevel@tonic-gate (const char *)"MOVETAB"); 16470Sstevel@tonic-gate (void) printf(Fmtptr, 16480Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_ptr)); 16490Sstevel@tonic-gate break; 16500Sstevel@tonic-gate case (DT_SYMINFO): 16510Sstevel@tonic-gate (void) printf(Fmttag, 16520Sstevel@tonic-gate (const char *)"SYMINFO"); 16530Sstevel@tonic-gate (void) printf(Fmtptr, 16540Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_ptr)); 16550Sstevel@tonic-gate break; 16560Sstevel@tonic-gate 16570Sstevel@tonic-gate /* 16580Sstevel@tonic-gate * SUNW: generic range. 16590Sstevel@tonic-gate */ 16600Sstevel@tonic-gate case (DT_RELACOUNT): 16610Sstevel@tonic-gate (void) printf(Fmttag, 16620Sstevel@tonic-gate (const char *)"RELACOUNT"); 16630Sstevel@tonic-gate (void) printf(Fmtptr, 16640Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_ptr)); 16650Sstevel@tonic-gate break; 16660Sstevel@tonic-gate case (DT_RELCOUNT): 16670Sstevel@tonic-gate (void) printf(Fmttag, 16680Sstevel@tonic-gate (const char *)"RELCOUNT"); 16690Sstevel@tonic-gate (void) printf(Fmtptr, 16700Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_ptr)); 16710Sstevel@tonic-gate break; 16720Sstevel@tonic-gate case (DT_FLAGS_1): 16730Sstevel@tonic-gate (void) printf(Fmttag, 16740Sstevel@tonic-gate (const char *)"FLAGS_1"); 16750Sstevel@tonic-gate value[0] = '\0'; 16760Sstevel@tonic-gate if (v_flag) { 16770Sstevel@tonic-gate if (p_dyn.d_un.d_val & DF_1_NOW) 16780Sstevel@tonic-gate (void) strcat(value, 16790Sstevel@tonic-gate (const char *)"NOW "); 16800Sstevel@tonic-gate if (p_dyn.d_un.d_val & DF_1_GLOBAL) 16810Sstevel@tonic-gate (void) strcat(value, 16820Sstevel@tonic-gate (const char *)"GLOBAL "); 16830Sstevel@tonic-gate if (p_dyn.d_un.d_val & DF_1_GROUP) 16840Sstevel@tonic-gate (void) strcat(value, 16850Sstevel@tonic-gate (const char *)"GROUP "); 16860Sstevel@tonic-gate if (p_dyn.d_un.d_val & DF_1_NODELETE) 16870Sstevel@tonic-gate (void) strcat(value, 16880Sstevel@tonic-gate (const char *)"NODELETE "); 16890Sstevel@tonic-gate if (p_dyn.d_un.d_val & DF_1_LOADFLTR) 16900Sstevel@tonic-gate (void) strcat(value, 16910Sstevel@tonic-gate (const char *)"LOADFLTR "); 16920Sstevel@tonic-gate if (p_dyn.d_un.d_val & DF_1_INITFIRST) 16930Sstevel@tonic-gate (void) strcat(value, 16940Sstevel@tonic-gate (const char *)"INITFIRST "); 16950Sstevel@tonic-gate if (p_dyn.d_un.d_val & DF_1_NOOPEN) 16960Sstevel@tonic-gate (void) strcat(value, 16970Sstevel@tonic-gate (const char *)"NOOPEN "); 16980Sstevel@tonic-gate if (p_dyn.d_un.d_val & DF_1_ORIGIN) 16990Sstevel@tonic-gate (void) strcat(value, 17000Sstevel@tonic-gate (const char *)"ORIGIN "); 17010Sstevel@tonic-gate if (p_dyn.d_un.d_val & DF_1_DIRECT) 17020Sstevel@tonic-gate (void) strcat(value, 17030Sstevel@tonic-gate (const char *)"DIRECT "); 17040Sstevel@tonic-gate if (p_dyn.d_un.d_val & DF_1_TRANS) 17050Sstevel@tonic-gate (void) strcat(value, 17060Sstevel@tonic-gate (const char *)"TRANS "); 17070Sstevel@tonic-gate if (p_dyn.d_un.d_val & DF_1_INTERPOSE) 17080Sstevel@tonic-gate (void) strcat(value, 17090Sstevel@tonic-gate (const char *)"INTERPOSE "); 17100Sstevel@tonic-gate if (p_dyn.d_un.d_val & DF_1_NODEFLIB) 17110Sstevel@tonic-gate (void) strcat(value, 17120Sstevel@tonic-gate (const char *)"NODEFLIB "); 17130Sstevel@tonic-gate if (p_dyn.d_un.d_val & DF_1_NODUMP) 17140Sstevel@tonic-gate (void) strcat(value, 17150Sstevel@tonic-gate (const char *)"NODUMP "); 17160Sstevel@tonic-gate if (p_dyn.d_un.d_val & DF_1_CONFALT) 17170Sstevel@tonic-gate (void) strcat(value, 17180Sstevel@tonic-gate (const char *)"CONFALT "); 17190Sstevel@tonic-gate if (p_dyn.d_un.d_val & DF_1_ENDFILTEE) 17200Sstevel@tonic-gate (void) strcat(value, 17210Sstevel@tonic-gate (const char *)"ENDFILTEE "); 17220Sstevel@tonic-gate if (p_dyn.d_un.d_val & DF_1_DISPRELDNE) 17230Sstevel@tonic-gate (void) strcat(value, 17240Sstevel@tonic-gate (const char *)"DISPRELDONE "); 17250Sstevel@tonic-gate if (p_dyn.d_un.d_val & DF_1_DISPRELPND) 17260Sstevel@tonic-gate (void) strcat(value, 17270Sstevel@tonic-gate (const char *)"DISPRELPND "); 17280Sstevel@tonic-gate if (p_dyn.d_un.d_val & DF_1_IGNMULDEF) 17290Sstevel@tonic-gate (void) strcat(value, 17300Sstevel@tonic-gate (const char *)"IGNMULDEF "); 17310Sstevel@tonic-gate if (p_dyn.d_un.d_val & DF_1_NOKSYMS) 17320Sstevel@tonic-gate (void) strcat(value, 17330Sstevel@tonic-gate (const char *)"NOKSYMS "); 17340Sstevel@tonic-gate } 17350Sstevel@tonic-gate if (v_flag && strlen(value)) 17360Sstevel@tonic-gate (void) printf("%s", value); 17370Sstevel@tonic-gate else 17380Sstevel@tonic-gate (void) printf(Fmtptr, 17390Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_ptr)); 17400Sstevel@tonic-gate break; 17410Sstevel@tonic-gate case (DT_VERSYM): 17420Sstevel@tonic-gate (void) printf(Fmttag, (const char *)"VERSYM"); 17430Sstevel@tonic-gate (void) printf(Fmtptr, 17440Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_ptr)); 17450Sstevel@tonic-gate break; 17460Sstevel@tonic-gate case (DT_VERDEF): 17470Sstevel@tonic-gate (void) printf(Fmttag, (const char *)"VERDEF"); 17480Sstevel@tonic-gate (void) printf(Fmtptr, 17490Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_ptr)); 17500Sstevel@tonic-gate break; 17510Sstevel@tonic-gate case (DT_VERDEFNUM): 17520Sstevel@tonic-gate (void) printf(Fmttag, 17530Sstevel@tonic-gate (const char *)"VERDEFNUM"); 17540Sstevel@tonic-gate (void) printf(Fmtptr, 17550Sstevel@tonic-gate EC_XWORD(p_dyn.d_un.d_val)); 17560Sstevel@tonic-gate break; 17570Sstevel@tonic-gate case (DT_VERNEED): 17580Sstevel@tonic-gate (void) printf(Fmttag, (const char *)"VERNEED"); 17590Sstevel@tonic-gate (void) printf(Fmtptr, 17600Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_ptr)); 17610Sstevel@tonic-gate break; 17620Sstevel@tonic-gate case (DT_VERNEEDNUM): 17630Sstevel@tonic-gate (void) printf(Fmttag, 17640Sstevel@tonic-gate (const char *)"VERNEEDNUM"); 17650Sstevel@tonic-gate (void) printf(Fmtptr, 17660Sstevel@tonic-gate EC_XWORD(p_dyn.d_un.d_val)); 17670Sstevel@tonic-gate break; 17680Sstevel@tonic-gate case (DT_AUXILIARY): 17690Sstevel@tonic-gate (void) printf(Fmttag, 17700Sstevel@tonic-gate (const char *)"AUXILIARY"); 17710Sstevel@tonic-gate if (v_flag) 17720Sstevel@tonic-gate dt_name = (char *)elf_strptr(elf_file, 17730Sstevel@tonic-gate link, p_dyn.d_un.d_ptr); 17740Sstevel@tonic-gate if (dt_name == NULL) 17750Sstevel@tonic-gate dt_name = (char *)UNKNOWN; 17760Sstevel@tonic-gate if (v_flag && strlen(dt_name)) 17770Sstevel@tonic-gate (void) printf("%s", dt_name); 17780Sstevel@tonic-gate else 17790Sstevel@tonic-gate (void) printf(Fmtptr, 17800Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_ptr)); 17810Sstevel@tonic-gate break; 17820Sstevel@tonic-gate case (DT_USED): 17830Sstevel@tonic-gate (void) printf(Fmttag, (const char *)"USED"); 17840Sstevel@tonic-gate if (v_flag) 17850Sstevel@tonic-gate dt_name = (char *)elf_strptr(elf_file, 17860Sstevel@tonic-gate link, p_dyn.d_un.d_ptr); 17870Sstevel@tonic-gate if (dt_name == NULL) 17880Sstevel@tonic-gate dt_name = (char *)UNKNOWN; 17890Sstevel@tonic-gate if (v_flag && strlen(dt_name)) 17900Sstevel@tonic-gate (void) printf("%s", dt_name); 17910Sstevel@tonic-gate else 17920Sstevel@tonic-gate (void) printf(Fmtptr, 17930Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_ptr)); 17940Sstevel@tonic-gate break; 17950Sstevel@tonic-gate case (DT_FILTER): 17960Sstevel@tonic-gate (void) printf(Fmttag, (const char *)"FILTER"); 17970Sstevel@tonic-gate if (v_flag) 17980Sstevel@tonic-gate dt_name = (char *)elf_strptr(elf_file, 17990Sstevel@tonic-gate link, p_dyn.d_un.d_ptr); 18000Sstevel@tonic-gate if (dt_name == NULL) 18010Sstevel@tonic-gate dt_name = (char *)UNKNOWN; 18020Sstevel@tonic-gate if (v_flag && strlen(dt_name)) 18030Sstevel@tonic-gate (void) printf("%s", dt_name); 18040Sstevel@tonic-gate else 18050Sstevel@tonic-gate (void) printf(Fmtptr, 18060Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_ptr)); 18070Sstevel@tonic-gate break; 18080Sstevel@tonic-gate 18090Sstevel@tonic-gate /* 18100Sstevel@tonic-gate * SUNW: machine specific range. 18110Sstevel@tonic-gate */ 18120Sstevel@tonic-gate case (DT_SPARC_REGISTER): 18130Sstevel@tonic-gate (void) printf(Fmttag, 18140Sstevel@tonic-gate (const char *)"REGISTER"); 18150Sstevel@tonic-gate (void) printf(Fmtptr, 18160Sstevel@tonic-gate EC_XWORD(p_dyn.d_un.d_val)); 18170Sstevel@tonic-gate break; 18180Sstevel@tonic-gate case (DT_DEPRECATED_SPARC_REGISTER): 18190Sstevel@tonic-gate (void) printf(Fmttag, 18200Sstevel@tonic-gate (const char *)"REGISTER"); 18210Sstevel@tonic-gate (void) printf("%#llx (deprecated value)", 18220Sstevel@tonic-gate EC_XWORD(p_dyn.d_un.d_val)); 18230Sstevel@tonic-gate break; 18240Sstevel@tonic-gate default: 18250Sstevel@tonic-gate (void) printf("%lld", EC_XWORD(p_dyn.d_tag)); 18260Sstevel@tonic-gate break; 18270Sstevel@tonic-gate } 18280Sstevel@tonic-gate (void) printf("\n"); 18290Sstevel@tonic-gate (void) gelf_getdyn(dyn_data, ii++, &p_dyn); 18300Sstevel@tonic-gate } 18310Sstevel@tonic-gate } 18320Sstevel@tonic-gate 18330Sstevel@tonic-gate /* 18340Sstevel@tonic-gate * Check for existence of static shared library information. 18350Sstevel@tonic-gate */ 18360Sstevel@tonic-gate (void) gelf_getehdr(elf_file, &p_ehdr); 18370Sstevel@tonic-gate while (header_num < p_ehdr.e_phnum) { 18380Sstevel@tonic-gate (void) gelf_getphdr(elf_file, header_num, &p_phdr); 18390Sstevel@tonic-gate if (p_phdr.p_type == PT_SHLIB) { 18400Sstevel@tonic-gate while (--lib_scns > 0) { 18410Sstevel@tonic-gate if (strcmp(l_scns->scn_name, ".lib") == 0) { 18420Sstevel@tonic-gate print_static(l_scns, filename); 18430Sstevel@tonic-gate } 18440Sstevel@tonic-gate l_scns++; 18450Sstevel@tonic-gate } 18460Sstevel@tonic-gate } 18470Sstevel@tonic-gate header_num++; 18480Sstevel@tonic-gate } 18490Sstevel@tonic-gate } 18500Sstevel@tonic-gate 18510Sstevel@tonic-gate /* 18520Sstevel@tonic-gate * Print the ELF header. Input is an ELF file descriptor 18530Sstevel@tonic-gate * and the filename. If f_flag is set, the ELF header is 18540Sstevel@tonic-gate * printed to stdout, otherwise the function returns after 18550Sstevel@tonic-gate * setting the pointer to the ELF header. Any values which 18560Sstevel@tonic-gate * are not known are printed in decimal. Fields must be updated 18570Sstevel@tonic-gate * as new values are added. 18580Sstevel@tonic-gate */ 18590Sstevel@tonic-gate static GElf_Ehdr * 18600Sstevel@tonic-gate dump_elf_header(Elf *elf_file, char *filename, GElf_Ehdr * elf_head_p) 18610Sstevel@tonic-gate { 18620Sstevel@tonic-gate int class, data; 18630Sstevel@tonic-gate int field; 18640Sstevel@tonic-gate 18650Sstevel@tonic-gate if (gelf_getehdr(elf_file, elf_head_p) == NULL) { 1866*1618Srie (void) fprintf(stderr, "%s: %s: %s\n", prog_name, filename, 1867*1618Srie elf_errmsg(-1)); 18680Sstevel@tonic-gate return (NULL); 18690Sstevel@tonic-gate } 18700Sstevel@tonic-gate 18710Sstevel@tonic-gate class = (int)elf_head_p->e_ident[4]; 18720Sstevel@tonic-gate 18730Sstevel@tonic-gate if (class == ELFCLASS64) 1874*1618Srie field = 21; 18750Sstevel@tonic-gate else 18760Sstevel@tonic-gate field = 13; 18770Sstevel@tonic-gate 18780Sstevel@tonic-gate if (!f_flag) 18790Sstevel@tonic-gate return (elf_head_p); 18800Sstevel@tonic-gate 18810Sstevel@tonic-gate if (!p_flag) { 1882*1618Srie (void) printf("\n **** ELF HEADER ****\n"); 1883*1618Srie (void) printf("%-*s%-11s%-*sMachine Version\n", 1884*1618Srie field, "Class", "Data", field, "Type"); 1885*1618Srie (void) printf("%-*s%-11s%-*sFlags Ehsize\n", 1886*1618Srie field, "Entry", "Phoff", field, "Shoff"); 1887*1618Srie (void) printf("%-*s%-11s%-*sShnum Shstrndx\n\n", 1888*1618Srie field, "Phentsize", "Phnum", field, "Shentsz"); 18890Sstevel@tonic-gate } 18900Sstevel@tonic-gate 18910Sstevel@tonic-gate if (!v_flag) { 18920Sstevel@tonic-gate (void) printf("%-*d%-11d%-*d%-12d%d\n", 18930Sstevel@tonic-gate field, elf_head_p->e_ident[4], 18940Sstevel@tonic-gate elf_head_p->e_ident[5], 18950Sstevel@tonic-gate field, (int)elf_head_p->e_type, 18960Sstevel@tonic-gate (int)elf_head_p->e_machine, 18970Sstevel@tonic-gate elf_head_p->e_version); 18980Sstevel@tonic-gate } else { 18990Sstevel@tonic-gate data = elf_head_p->e_ident[5]; 19000Sstevel@tonic-gate 19010Sstevel@tonic-gate switch (class) { 19020Sstevel@tonic-gate case ELFCLASSNONE: 19030Sstevel@tonic-gate (void) printf("%-*s", field, "None"); 19040Sstevel@tonic-gate break; 19050Sstevel@tonic-gate case ELFCLASS32: 19060Sstevel@tonic-gate (void) printf("%-*s", field, "32-bit"); 19070Sstevel@tonic-gate break; 19080Sstevel@tonic-gate case ELFCLASS64: 19090Sstevel@tonic-gate (void) printf("%-*s", field, "64-bit"); 19100Sstevel@tonic-gate break; 19110Sstevel@tonic-gate default: 19120Sstevel@tonic-gate (void) printf("%-*d", field, class); 19130Sstevel@tonic-gate break; 19140Sstevel@tonic-gate } 19150Sstevel@tonic-gate switch (data) { 19160Sstevel@tonic-gate case ELFDATANONE: 19170Sstevel@tonic-gate (void) printf("%-11s", "None "); 19180Sstevel@tonic-gate break; 19190Sstevel@tonic-gate case ELFDATA2LSB: 19200Sstevel@tonic-gate (void) printf("%-11s", "2LSB "); 19210Sstevel@tonic-gate break; 19220Sstevel@tonic-gate case ELFDATA2MSB: 19230Sstevel@tonic-gate (void) printf("%-11s", "2MSB "); 19240Sstevel@tonic-gate break; 19250Sstevel@tonic-gate default: 19260Sstevel@tonic-gate (void) printf("%-11d", data); 19270Sstevel@tonic-gate break; 19280Sstevel@tonic-gate } 19290Sstevel@tonic-gate 19300Sstevel@tonic-gate switch (elf_head_p->e_type) { 19310Sstevel@tonic-gate case ET_NONE: 19320Sstevel@tonic-gate (void) printf("%-*s", field, "None"); 19330Sstevel@tonic-gate break; 19340Sstevel@tonic-gate case ET_REL: 19350Sstevel@tonic-gate (void) printf("%-*s", field, "Reloc"); 19360Sstevel@tonic-gate break; 19370Sstevel@tonic-gate case ET_EXEC: 19380Sstevel@tonic-gate (void) printf("%-*s", field, "Exec"); 19390Sstevel@tonic-gate break; 19400Sstevel@tonic-gate case ET_DYN: 19410Sstevel@tonic-gate (void) printf("%-*s", field, "Dyn"); 19420Sstevel@tonic-gate break; 19430Sstevel@tonic-gate case ET_CORE: 19440Sstevel@tonic-gate (void) printf("%-*s", field, "Core"); 19450Sstevel@tonic-gate break; 19460Sstevel@tonic-gate default: 19470Sstevel@tonic-gate (void) printf("%-*d", field, 19480Sstevel@tonic-gate EC_WORD(elf_head_p->e_type)); 19490Sstevel@tonic-gate break; 19500Sstevel@tonic-gate } 19510Sstevel@tonic-gate switch (elf_head_p->e_machine) { 19520Sstevel@tonic-gate case EM_NONE: 19530Sstevel@tonic-gate (void) printf("%-12s", "No mach"); 19540Sstevel@tonic-gate break; 19550Sstevel@tonic-gate case EM_M32: 19560Sstevel@tonic-gate (void) printf("%-12s", "WE32100"); 19570Sstevel@tonic-gate break; 19580Sstevel@tonic-gate case EM_SPARC: 19590Sstevel@tonic-gate (void) printf("%-12s", "SPARC"); 19600Sstevel@tonic-gate break; 19610Sstevel@tonic-gate case EM_SPARCV9: 19620Sstevel@tonic-gate (void) printf("%-12s", "SPARCV9"); 19630Sstevel@tonic-gate break; 19640Sstevel@tonic-gate case EM_386: 19650Sstevel@tonic-gate (void) printf("%-12s", "80386"); 19660Sstevel@tonic-gate break; 19670Sstevel@tonic-gate case EM_68K: 19680Sstevel@tonic-gate (void) printf("%-12s", "68000"); 19690Sstevel@tonic-gate break; 19700Sstevel@tonic-gate case EM_88K: 19710Sstevel@tonic-gate (void) printf("%-12s", "88000"); 19720Sstevel@tonic-gate break; 19730Sstevel@tonic-gate case EM_486: 19740Sstevel@tonic-gate (void) printf("%-12s", "80486"); 19750Sstevel@tonic-gate break; 19760Sstevel@tonic-gate case EM_860: 19770Sstevel@tonic-gate (void) printf("%-12s", "i860"); 19780Sstevel@tonic-gate break; 19790Sstevel@tonic-gate case EM_MIPS: 19800Sstevel@tonic-gate (void) printf("%-12s", "RS3000_BE"); 19810Sstevel@tonic-gate break; 19820Sstevel@tonic-gate case EM_MIPS_RS3_LE: 19830Sstevel@tonic-gate (void) printf("%-12s", "RS3000_LE"); 19840Sstevel@tonic-gate break; 19850Sstevel@tonic-gate case EM_RS6000: 19860Sstevel@tonic-gate (void) printf("%-12s", "RS6000"); 19870Sstevel@tonic-gate break; 19880Sstevel@tonic-gate case EM_PA_RISC: 19890Sstevel@tonic-gate (void) printf("%-12s", "PA_RISC"); 19900Sstevel@tonic-gate break; 19910Sstevel@tonic-gate case EM_nCUBE: 19920Sstevel@tonic-gate (void) printf("%-12s", "nCUBE"); 19930Sstevel@tonic-gate break; 19940Sstevel@tonic-gate case EM_VPP500: 19950Sstevel@tonic-gate (void) printf("%-12s", "VPP500"); 19960Sstevel@tonic-gate break; 19970Sstevel@tonic-gate case EM_SPARC32PLUS: 19980Sstevel@tonic-gate (void) printf("%-12s", "SPARC32PLUS"); 19990Sstevel@tonic-gate break; 20000Sstevel@tonic-gate case EM_PPC: 20010Sstevel@tonic-gate (void) printf("%-12s", "PowerPC"); 20020Sstevel@tonic-gate break; 20030Sstevel@tonic-gate case EM_IA_64: 20040Sstevel@tonic-gate (void) printf("%-12s", "IA64"); 20050Sstevel@tonic-gate break; 20060Sstevel@tonic-gate default: 20070Sstevel@tonic-gate (void) printf("%-12d", EC_WORD(elf_head_p->e_machine)); 20080Sstevel@tonic-gate } 20090Sstevel@tonic-gate switch (elf_head_p->e_version) { 20100Sstevel@tonic-gate case EV_NONE: 20110Sstevel@tonic-gate (void) printf("Invalid\n"); 20120Sstevel@tonic-gate break; 20130Sstevel@tonic-gate case EV_CURRENT: 20140Sstevel@tonic-gate (void) printf("Current\n"); 20150Sstevel@tonic-gate break; 20160Sstevel@tonic-gate default: 20170Sstevel@tonic-gate (void) printf("%d\n", elf_head_p->e_version); 20180Sstevel@tonic-gate } 20190Sstevel@tonic-gate } 20200Sstevel@tonic-gate (void) printf("%-#*llx%-#11llx%-#*llx%-#12x%#x\n", 20210Sstevel@tonic-gate field, EC_ADDR(elf_head_p->e_entry), 20220Sstevel@tonic-gate EC_OFF(elf_head_p->e_phoff), 20230Sstevel@tonic-gate field, EC_OFF(elf_head_p->e_shoff), 20240Sstevel@tonic-gate EC_WORD(elf_head_p->e_flags), 20250Sstevel@tonic-gate EC_WORD(elf_head_p->e_ehsize)); 20260Sstevel@tonic-gate if (!v_flag || (elf_head_p->e_shstrndx != SHN_XINDEX)) { 20270Sstevel@tonic-gate (void) printf("%-#*x%-11u%-#*x%-12u%u\n", 20280Sstevel@tonic-gate field, EC_WORD(elf_head_p->e_phentsize), 20290Sstevel@tonic-gate EC_WORD(elf_head_p->e_phnum), 20300Sstevel@tonic-gate field, EC_WORD(elf_head_p->e_shentsize), 20310Sstevel@tonic-gate EC_WORD(elf_head_p->e_shnum), 20320Sstevel@tonic-gate EC_WORD(elf_head_p->e_shstrndx)); 20330Sstevel@tonic-gate } else { 20340Sstevel@tonic-gate (void) printf("%-#*x%-11u%-#*x%-12uXINDEX\n", 20350Sstevel@tonic-gate field, EC_WORD(elf_head_p->e_phentsize), 20360Sstevel@tonic-gate EC_WORD(elf_head_p->e_phnum), 20370Sstevel@tonic-gate field, EC_WORD(elf_head_p->e_shentsize), 20380Sstevel@tonic-gate EC_WORD(elf_head_p->e_shnum)); 20390Sstevel@tonic-gate } 20400Sstevel@tonic-gate if ((elf_head_p->e_shnum == 0) && (elf_head_p->e_shoff > 0)) { 20410Sstevel@tonic-gate Elf_Scn *scn; 20420Sstevel@tonic-gate GElf_Shdr shdr0; 20430Sstevel@tonic-gate int field; 20440Sstevel@tonic-gate 20450Sstevel@tonic-gate if (gelf_getclass(elf_file) == ELFCLASS64) 2046*1618Srie field = 21; 20470Sstevel@tonic-gate else 2048*1618Srie field = 13; 20490Sstevel@tonic-gate if (!p_flag) { 20500Sstevel@tonic-gate (void) printf("\n **** SECTION HEADER[0] " 20510Sstevel@tonic-gate "{Elf Extensions} ****\n"); 20520Sstevel@tonic-gate (void) printf( 20530Sstevel@tonic-gate "[No]\tType\tFlags\t%-*s %-*s%-*s%sName\n", 20540Sstevel@tonic-gate field, "Addr", field, "Offset", field, 20550Sstevel@tonic-gate "Size(shnum)", 20560Sstevel@tonic-gate /* compatibility: tab for elf32 */ 2057*1618Srie (field == 13) ? "\t" : " "); 20580Sstevel@tonic-gate (void) printf("\tLn(strndx) Info\t%-*s Entsize\n", 20590Sstevel@tonic-gate field, "Adralgn"); 20600Sstevel@tonic-gate } 20610Sstevel@tonic-gate if ((scn = elf_getscn(elf_file, 0)) == NULL) { 20620Sstevel@tonic-gate (void) fprintf(stderr, 20630Sstevel@tonic-gate "%s: %s: elf_getscn failed: %s\n", 20640Sstevel@tonic-gate prog_name, filename, elf_errmsg(-1)); 20650Sstevel@tonic-gate return (NULL); 20660Sstevel@tonic-gate } 20670Sstevel@tonic-gate if (gelf_getshdr(scn, &shdr0) == 0) { 20680Sstevel@tonic-gate (void) fprintf(stderr, 20690Sstevel@tonic-gate "%s: %s: gelf_getshdr: %s\n", 20700Sstevel@tonic-gate prog_name, filename, elf_errmsg(-1)); 20710Sstevel@tonic-gate return (NULL); 20720Sstevel@tonic-gate } 20730Sstevel@tonic-gate (void) printf("[0]\t%u\t%llu\t", EC_WORD(shdr0.sh_type), 20740Sstevel@tonic-gate EC_XWORD(shdr0.sh_flags)); 20750Sstevel@tonic-gate 20760Sstevel@tonic-gate /* 20770Sstevel@tonic-gate * LINTED - field and EC_XWORD cause -#*llu complaints that 20780Sstevel@tonic-gate * even this comment can't shutup. 20790Sstevel@tonic-gate */ 20800Sstevel@tonic-gate (void) printf("%-#*llx %-#*llx%-#*llu%s%-#*u\n", 20810Sstevel@tonic-gate field, EC_ADDR(shdr0.sh_addr), 20820Sstevel@tonic-gate field, EC_OFF(shdr0.sh_offset), 20830Sstevel@tonic-gate field, EC_XWORD(shdr0.sh_size), 20840Sstevel@tonic-gate /* compatibility: tab for elf32 */ 2085*1618Srie ((field == 13) ? "\t" : " "), 20860Sstevel@tonic-gate field, EC_WORD(shdr0.sh_name)); 20870Sstevel@tonic-gate 20880Sstevel@tonic-gate (void) printf("\t%u\t%u\t%-#*llx %-#*llx\n", 20890Sstevel@tonic-gate EC_WORD(shdr0.sh_link), 20900Sstevel@tonic-gate EC_WORD(shdr0.sh_info), 20910Sstevel@tonic-gate field, EC_XWORD(shdr0.sh_addralign), 20920Sstevel@tonic-gate field, EC_XWORD(shdr0.sh_entsize)); 20930Sstevel@tonic-gate } 20940Sstevel@tonic-gate (void) printf("\n"); 20950Sstevel@tonic-gate 20960Sstevel@tonic-gate return (elf_head_p); 20970Sstevel@tonic-gate } 20980Sstevel@tonic-gate 20990Sstevel@tonic-gate /* 21000Sstevel@tonic-gate * Print section contents. Input is an ELF file descriptor, 21010Sstevel@tonic-gate * the ELF header, the SCNTAB structure, 21020Sstevel@tonic-gate * the number of symbols, and the filename. 21030Sstevel@tonic-gate * The number of sections, 21040Sstevel@tonic-gate * and the offset into the SCNTAB structure will be 21050Sstevel@tonic-gate * set in dump_section if d_flag or n_flag are set. 21060Sstevel@tonic-gate * If v_flag is set, sections which can be interpreted will 21070Sstevel@tonic-gate * be interpreted, otherwise raw data will be output in hexidecimal. 21080Sstevel@tonic-gate */ 21090Sstevel@tonic-gate static void 21100Sstevel@tonic-gate print_section(Elf *elf_file, 21110Sstevel@tonic-gate GElf_Ehdr *p_ehdr, SCNTAB *p, int num_scns, char *filename) 21120Sstevel@tonic-gate { 21130Sstevel@tonic-gate unsigned char *p_sec; 21140Sstevel@tonic-gate int i; 21150Sstevel@tonic-gate size_t size; 21160Sstevel@tonic-gate 21170Sstevel@tonic-gate for (i = 0; i < num_scns; i++, p++) { 21180Sstevel@tonic-gate GElf_Shdr shdr; 21190Sstevel@tonic-gate 21200Sstevel@tonic-gate size = 0; 21210Sstevel@tonic-gate if (s_flag && !v_flag) 21220Sstevel@tonic-gate p_sec = (unsigned char *)get_rawscn(p->p_sd, &size); 21230Sstevel@tonic-gate else 21240Sstevel@tonic-gate p_sec = (unsigned char *)get_scndata(p->p_sd, &size); 21250Sstevel@tonic-gate 21260Sstevel@tonic-gate if ((gelf_getshdr(p->p_sd, &shdr) != NULL) && 21270Sstevel@tonic-gate (shdr.sh_type == SHT_NOBITS)) { 21280Sstevel@tonic-gate continue; 21290Sstevel@tonic-gate } 21300Sstevel@tonic-gate if (s_flag && !v_flag) { 21310Sstevel@tonic-gate (void) printf("\n%s:\n", p->scn_name); 21320Sstevel@tonic-gate print_rawdata(p_sec, size); 21330Sstevel@tonic-gate continue; 21340Sstevel@tonic-gate } 21350Sstevel@tonic-gate if (shdr.sh_type == SHT_SYMTAB) { 21360Sstevel@tonic-gate dump_symbol_table(elf_file, p, filename); 21370Sstevel@tonic-gate continue; 21380Sstevel@tonic-gate } 21390Sstevel@tonic-gate if (shdr.sh_type == SHT_DYNSYM) { 21400Sstevel@tonic-gate dump_symbol_table(elf_file, p, filename); 21410Sstevel@tonic-gate continue; 21420Sstevel@tonic-gate } 21430Sstevel@tonic-gate if (shdr.sh_type == SHT_STRTAB) { 21440Sstevel@tonic-gate dump_string_table(p, 1); 21450Sstevel@tonic-gate continue; 21460Sstevel@tonic-gate } 21470Sstevel@tonic-gate if (shdr.sh_type == SHT_RELA) { 21480Sstevel@tonic-gate dump_reloc_table(elf_file, p_ehdr, p, 1, filename); 21490Sstevel@tonic-gate continue; 21500Sstevel@tonic-gate } 21510Sstevel@tonic-gate if (shdr.sh_type == SHT_REL) { 21520Sstevel@tonic-gate dump_reloc_table(elf_file, p_ehdr, p, 1, filename); 21530Sstevel@tonic-gate continue; 21540Sstevel@tonic-gate } 21550Sstevel@tonic-gate if (shdr.sh_type == SHT_DYNAMIC) { 21560Sstevel@tonic-gate dump_dynamic(elf_file, p, 1, filename); 21570Sstevel@tonic-gate continue; 21580Sstevel@tonic-gate } 21590Sstevel@tonic-gate 21600Sstevel@tonic-gate (void) printf("\n%s:\n", p->scn_name); 21610Sstevel@tonic-gate print_rawdata(p_sec, size); 21620Sstevel@tonic-gate } 21630Sstevel@tonic-gate (void) printf("\n"); 21640Sstevel@tonic-gate } 21650Sstevel@tonic-gate 21660Sstevel@tonic-gate /* 21670Sstevel@tonic-gate * Print section contents. This function does not print the contents 21680Sstevel@tonic-gate * of the sections but sets up the parameters and then calls 21690Sstevel@tonic-gate * print_section to print the contents. Calling another function to print 21700Sstevel@tonic-gate * the contents allows both -d and -n to work correctly 21710Sstevel@tonic-gate * simultaneously. Input is an ELF file descriptor, the ELF header, 21720Sstevel@tonic-gate * the SCNTAB structure, the number of sections, and the filename. 21730Sstevel@tonic-gate * Set the range of sections if d_flag, and set section name if 21740Sstevel@tonic-gate * n_flag. 21750Sstevel@tonic-gate */ 21760Sstevel@tonic-gate static void 21770Sstevel@tonic-gate dump_section(Elf *elf_file, 21780Sstevel@tonic-gate GElf_Ehdr *p_ehdr, SCNTAB *s, int num_scns, char *filename) 21790Sstevel@tonic-gate { 21800Sstevel@tonic-gate SCNTAB *n_range, *d_range; /* for use with -n and -d modifiers */ 21810Sstevel@tonic-gate int i; 21820Sstevel@tonic-gate int found_it = 0; /* for use with -n section_name */ 21830Sstevel@tonic-gate 21840Sstevel@tonic-gate if (n_flag) { 21850Sstevel@tonic-gate n_range = s; 21860Sstevel@tonic-gate 21870Sstevel@tonic-gate for (i = 0; i < num_scns; i++, n_range++) { 21880Sstevel@tonic-gate if ((strcmp(name, n_range->scn_name)) != 0) 21890Sstevel@tonic-gate continue; 21900Sstevel@tonic-gate else { 21910Sstevel@tonic-gate found_it = 1; 21920Sstevel@tonic-gate print_section(elf_file, p_ehdr, 21930Sstevel@tonic-gate n_range, 1, filename); 21940Sstevel@tonic-gate } 21950Sstevel@tonic-gate } 21960Sstevel@tonic-gate 21970Sstevel@tonic-gate if (!found_it) { 21980Sstevel@tonic-gate (void) fprintf(stderr, "%s: %s: %s not found\n", 21990Sstevel@tonic-gate prog_name, filename, name); 22000Sstevel@tonic-gate } 22010Sstevel@tonic-gate } /* end n_flag */ 22020Sstevel@tonic-gate 22030Sstevel@tonic-gate if (d_flag) { 22040Sstevel@tonic-gate d_range = s; 22050Sstevel@tonic-gate d_num = check_range(d_low, d_hi, num_scns, filename); 22060Sstevel@tonic-gate if (d_num < 0) 22070Sstevel@tonic-gate return; 22080Sstevel@tonic-gate d_range += d_low - 1; 22090Sstevel@tonic-gate 22100Sstevel@tonic-gate print_section(elf_file, p_ehdr, d_range, d_num, filename); 22110Sstevel@tonic-gate } /* end d_flag */ 22120Sstevel@tonic-gate 22130Sstevel@tonic-gate if (!n_flag && !d_flag) 22140Sstevel@tonic-gate print_section(elf_file, p_ehdr, s, num_scns, filename); 22150Sstevel@tonic-gate } 22160Sstevel@tonic-gate 22170Sstevel@tonic-gate /* 22180Sstevel@tonic-gate * Print the section header table. This function does not print the contents 22190Sstevel@tonic-gate * of the section headers but sets up the parameters and then calls 22200Sstevel@tonic-gate * print_shdr to print the contents. Calling another function to print 22210Sstevel@tonic-gate * the contents allows both -d and -n to work correctly 22220Sstevel@tonic-gate * simultaneously. Input is the SCNTAB structure, 22230Sstevel@tonic-gate * the number of sections from the ELF header, and the filename. 22240Sstevel@tonic-gate * Set the range of section headers to print if d_flag, and set 22250Sstevel@tonic-gate * name of section header to print if n_flag. 22260Sstevel@tonic-gate */ 22270Sstevel@tonic-gate static void 22280Sstevel@tonic-gate dump_shdr(Elf *elf_file, SCNTAB *s, int num_scns, char *filename) 22290Sstevel@tonic-gate { 22300Sstevel@tonic-gate 22310Sstevel@tonic-gate SCNTAB *n_range, *d_range; /* for use with -n and -d modifiers */ 22320Sstevel@tonic-gate int field; 22330Sstevel@tonic-gate int i; 22340Sstevel@tonic-gate int found_it = 0; /* for use with -n section_name */ 22350Sstevel@tonic-gate 22360Sstevel@tonic-gate if (gelf_getclass(elf_file) == ELFCLASS64) 2237*1618Srie field = 21; 22380Sstevel@tonic-gate else 2239*1618Srie field = 13; 22400Sstevel@tonic-gate 22410Sstevel@tonic-gate if (!p_flag) { 22420Sstevel@tonic-gate (void) printf("\n **** SECTION HEADER TABLE ****\n"); 22430Sstevel@tonic-gate (void) printf("[No]\tType\tFlags\t%-*s %-*s %-*s%sName\n", 22440Sstevel@tonic-gate field, "Addr", field, "Offset", field, "Size", 22450Sstevel@tonic-gate /* compatibility: tab for elf32 */ 2246*1618Srie (field == 13) ? "\t" : " "); 22470Sstevel@tonic-gate (void) printf("\tLink\tInfo\t%-*s Entsize\n\n", 22480Sstevel@tonic-gate field, "Adralgn"); 22490Sstevel@tonic-gate } 22500Sstevel@tonic-gate 22510Sstevel@tonic-gate if (n_flag) { 22520Sstevel@tonic-gate n_range = s; 22530Sstevel@tonic-gate 22540Sstevel@tonic-gate for (i = 1; i <= num_scns; i++, n_range++) { 22550Sstevel@tonic-gate if ((strcmp(name, n_range->scn_name)) != 0) 22560Sstevel@tonic-gate continue; 22570Sstevel@tonic-gate else { 22580Sstevel@tonic-gate found_it = 1; 22590Sstevel@tonic-gate print_shdr(elf_file, n_range, 1, i); 22600Sstevel@tonic-gate } 22610Sstevel@tonic-gate } 22620Sstevel@tonic-gate 22630Sstevel@tonic-gate if (!found_it) { 22640Sstevel@tonic-gate (void) fprintf(stderr, "%s: %s: %s not found\n", 22650Sstevel@tonic-gate prog_name, filename, name); 22660Sstevel@tonic-gate } 22670Sstevel@tonic-gate } /* end n_flag */ 22680Sstevel@tonic-gate 22690Sstevel@tonic-gate if (d_flag) { 22700Sstevel@tonic-gate d_range = s; 22710Sstevel@tonic-gate d_num = check_range(d_low, d_hi, num_scns, filename); 22720Sstevel@tonic-gate if (d_num < 0) 22730Sstevel@tonic-gate return; 22740Sstevel@tonic-gate d_range += d_low - 1; 22750Sstevel@tonic-gate 22760Sstevel@tonic-gate print_shdr(elf_file, d_range, d_num, d_low); 22770Sstevel@tonic-gate } /* end d_flag */ 22780Sstevel@tonic-gate 22790Sstevel@tonic-gate if (!n_flag && !d_flag) 22800Sstevel@tonic-gate print_shdr(elf_file, s, num_scns, 1); 22810Sstevel@tonic-gate } 22820Sstevel@tonic-gate 22830Sstevel@tonic-gate /* 22840Sstevel@tonic-gate * Process all of the command line options (except 22850Sstevel@tonic-gate * for -a, -g, -f, and -o). All of the options processed 22860Sstevel@tonic-gate * by this function require the presence of the section 22870Sstevel@tonic-gate * header table and will not be processed if it is not present. 22880Sstevel@tonic-gate * Set up a buffer containing section name, section header, 22890Sstevel@tonic-gate * and section descriptor for each section in the file. This 22900Sstevel@tonic-gate * structure is used to avoid duplicate calls to libelf functions. 22910Sstevel@tonic-gate * Structure members for the symbol table, the debugging information, 22920Sstevel@tonic-gate * and the line number information are global. All of the 22930Sstevel@tonic-gate * rest are local. 22940Sstevel@tonic-gate */ 22950Sstevel@tonic-gate static void 22960Sstevel@tonic-gate dump_section_table(Elf *elf_file, GElf_Ehdr *elf_head_p, char *filename) 22970Sstevel@tonic-gate { 22980Sstevel@tonic-gate 22990Sstevel@tonic-gate static SCNTAB *buffer, *p_scns; 23000Sstevel@tonic-gate Elf_Scn *scn = 0; 23010Sstevel@tonic-gate char *s_name = NULL; 23020Sstevel@tonic-gate int found = 0; 23030Sstevel@tonic-gate unsigned int num_scns; 23040Sstevel@tonic-gate size_t shstrndx; 23050Sstevel@tonic-gate size_t shnum; 23060Sstevel@tonic-gate 23070Sstevel@tonic-gate 23080Sstevel@tonic-gate if (elf_getshnum(elf_file, &shnum) == 0) { 23090Sstevel@tonic-gate (void) fprintf(stderr, 23100Sstevel@tonic-gate "%s: %s: elf_getshnum failed: %s\n", 23110Sstevel@tonic-gate prog_name, filename, elf_errmsg(-1)); 23120Sstevel@tonic-gate return; 23130Sstevel@tonic-gate } 23140Sstevel@tonic-gate if (elf_getshstrndx(elf_file, &shstrndx) == 0) { 23150Sstevel@tonic-gate (void) fprintf(stderr, 23160Sstevel@tonic-gate "%s: %s: elf_getshstrndx failed: %s\n", 23170Sstevel@tonic-gate prog_name, filename, elf_errmsg(-1)); 23180Sstevel@tonic-gate return; 23190Sstevel@tonic-gate } 23200Sstevel@tonic-gate 23210Sstevel@tonic-gate if ((buffer = calloc(shnum, sizeof (SCNTAB))) == NULL) { 23220Sstevel@tonic-gate (void) fprintf(stderr, "%s: %s: cannot calloc space\n", 23230Sstevel@tonic-gate prog_name, filename); 23240Sstevel@tonic-gate return; 23250Sstevel@tonic-gate } 23260Sstevel@tonic-gate /* LINTED */ 23270Sstevel@tonic-gate num_scns = (int)shnum - 1; 23280Sstevel@tonic-gate 23290Sstevel@tonic-gate p_symtab = (SCNTAB *)0; 23300Sstevel@tonic-gate p_dynsym = (SCNTAB *)0; 23310Sstevel@tonic-gate p_scns = buffer; 23320Sstevel@tonic-gate p_head_scns = buffer; 23330Sstevel@tonic-gate 23340Sstevel@tonic-gate while ((scn = elf_nextscn(elf_file, scn)) != 0) { 23350Sstevel@tonic-gate if ((gelf_getshdr(scn, &buffer->p_shdr)) == 0) { 23360Sstevel@tonic-gate (void) fprintf(stderr, 23370Sstevel@tonic-gate "%s: %s: %s\n", prog_name, filename, elf_errmsg(-1)); 23380Sstevel@tonic-gate return; 23390Sstevel@tonic-gate } 23400Sstevel@tonic-gate s_name = (char *)elf_strptr(elf_file, 23410Sstevel@tonic-gate shstrndx, buffer->p_shdr.sh_name); 23420Sstevel@tonic-gate buffer->scn_name = s_name ? s_name : (char *)UNKNOWN; 23430Sstevel@tonic-gate buffer->p_sd = scn; 23440Sstevel@tonic-gate 23450Sstevel@tonic-gate if (buffer->p_shdr.sh_type == SHT_SYMTAB) { 23460Sstevel@tonic-gate found += 1; 23470Sstevel@tonic-gate p_symtab = buffer; 23480Sstevel@tonic-gate } 23490Sstevel@tonic-gate if (buffer->p_shdr.sh_type == SHT_DYNSYM) 23500Sstevel@tonic-gate p_dynsym = buffer; 23510Sstevel@tonic-gate buffer++; 23520Sstevel@tonic-gate } 23530Sstevel@tonic-gate 23540Sstevel@tonic-gate /* 23550Sstevel@tonic-gate * These functions depend upon the presence of the section header table 23560Sstevel@tonic-gate * and will not be invoked in its absence 23570Sstevel@tonic-gate */ 23580Sstevel@tonic-gate if (h_flag) { 23590Sstevel@tonic-gate dump_shdr(elf_file, p_scns, num_scns, filename); 23600Sstevel@tonic-gate } 23610Sstevel@tonic-gate if (p_symtab && (t_flag || T_flag)) { 23620Sstevel@tonic-gate dump_symbol_table(elf_file, p_symtab, filename); 23630Sstevel@tonic-gate } 23640Sstevel@tonic-gate if (c_flag) { 23650Sstevel@tonic-gate dump_string_table(p_scns, num_scns); 23660Sstevel@tonic-gate } 23670Sstevel@tonic-gate if (r_flag) { 23680Sstevel@tonic-gate dump_reloc_table(elf_file, elf_head_p, 23690Sstevel@tonic-gate p_scns, num_scns, filename); 23700Sstevel@tonic-gate } 23710Sstevel@tonic-gate if (L_flag) { 23720Sstevel@tonic-gate dump_dynamic(elf_file, p_scns, num_scns, filename); 23730Sstevel@tonic-gate } 23740Sstevel@tonic-gate if (s_flag) { 23750Sstevel@tonic-gate dump_section(elf_file, elf_head_p, p_scns, 23760Sstevel@tonic-gate num_scns, filename); 23770Sstevel@tonic-gate } 23780Sstevel@tonic-gate } 23790Sstevel@tonic-gate 23800Sstevel@tonic-gate /* 23810Sstevel@tonic-gate * Load the archive string table(s) (for extended-length strings) 23820Sstevel@tonic-gate * into an in-core table/list 23830Sstevel@tonic-gate */ 23840Sstevel@tonic-gate static struct stab_list_s * 23850Sstevel@tonic-gate load_arstring_table(struct stab_list_s *STabList, 23860Sstevel@tonic-gate int fd, Elf *elf_file, Elf_Arhdr *p_ar, char *filename) 23870Sstevel@tonic-gate { 23880Sstevel@tonic-gate off_t here; 23890Sstevel@tonic-gate struct stab_list_s *STL_entry, *STL_next; 23900Sstevel@tonic-gate 23910Sstevel@tonic-gate if (p_ar) { 23920Sstevel@tonic-gate STL_entry = malloc(sizeof (struct stab_list_s)); 23930Sstevel@tonic-gate STL_entry->next = 0; 23940Sstevel@tonic-gate STL_entry->strings = 0; 23950Sstevel@tonic-gate STL_entry->size = 0; 23960Sstevel@tonic-gate 23970Sstevel@tonic-gate if (!STabList) 23980Sstevel@tonic-gate STabList = STL_entry; 23990Sstevel@tonic-gate else { 24000Sstevel@tonic-gate STL_next = STabList; 24010Sstevel@tonic-gate while (STL_next->next != (void *)0) 24020Sstevel@tonic-gate STL_next = STL_next->next; 24030Sstevel@tonic-gate STL_next->next = STL_entry; 24040Sstevel@tonic-gate } 24050Sstevel@tonic-gate 24060Sstevel@tonic-gate STL_entry->size = p_ar->ar_size; 24070Sstevel@tonic-gate STL_entry->strings = malloc(p_ar->ar_size); 24080Sstevel@tonic-gate here = elf_getbase(elf_file); 24090Sstevel@tonic-gate if ((lseek(fd, here, 0)) != here) { 24100Sstevel@tonic-gate (void) fprintf(stderr, 24110Sstevel@tonic-gate "%s: %s: could not lseek\n", prog_name, filename); 24120Sstevel@tonic-gate } 24130Sstevel@tonic-gate 24140Sstevel@tonic-gate if ((read(fd, STL_entry->strings, p_ar->ar_size)) == -1) { 24150Sstevel@tonic-gate (void) fprintf(stderr, 24160Sstevel@tonic-gate "%s: %s: could not read\n", prog_name, filename); 24170Sstevel@tonic-gate } 24180Sstevel@tonic-gate } 24190Sstevel@tonic-gate return (STabList); 24200Sstevel@tonic-gate } 24210Sstevel@tonic-gate 24220Sstevel@tonic-gate /* 24230Sstevel@tonic-gate * Print the archive header for each member of an archive. 24240Sstevel@tonic-gate * Also call ar_sym_read to print the symbols in the 24250Sstevel@tonic-gate * archive symbol table if g_flag. Input is a file descriptor, 24260Sstevel@tonic-gate * an ELF file descriptor, and the filename. Putting the call 24270Sstevel@tonic-gate * to dump the archive symbol table in this function is more 24280Sstevel@tonic-gate * efficient since it is necessary to examine the archive member 24290Sstevel@tonic-gate * name in the archive header to determine which member is the 24300Sstevel@tonic-gate * symbol table. 24310Sstevel@tonic-gate */ 24320Sstevel@tonic-gate static void 24330Sstevel@tonic-gate dump_ar_hdr(int fd, Elf *elf_file, char *filename) 24340Sstevel@tonic-gate { 24350Sstevel@tonic-gate extern int v_flag, g_flag, a_flag, p_flag; 24360Sstevel@tonic-gate Elf_Arhdr *p_ar; 24370Sstevel@tonic-gate Elf *arf; 24380Sstevel@tonic-gate Elf_Cmd cmd; 24390Sstevel@tonic-gate int title = 0; 24400Sstevel@tonic-gate int err = 0; 24410Sstevel@tonic-gate 24420Sstevel@tonic-gate char buf[DATESIZE]; 24430Sstevel@tonic-gate 24440Sstevel@tonic-gate cmd = ELF_C_READ; 24450Sstevel@tonic-gate while ((arf = elf_begin(fd, cmd, elf_file)) != 0) { 24460Sstevel@tonic-gate p_ar = elf_getarhdr(arf); 24470Sstevel@tonic-gate if (p_ar == NULL) { 24480Sstevel@tonic-gate (void) fprintf(stderr, 24490Sstevel@tonic-gate "%s: %s: %s\n", prog_name, filename, elf_errmsg(-1)); 24500Sstevel@tonic-gate continue; 24510Sstevel@tonic-gate } 24520Sstevel@tonic-gate if (strcmp(p_ar->ar_name, "/") == 0) { 24530Sstevel@tonic-gate if (g_flag) 24540Sstevel@tonic-gate ar_sym_read(elf_file, filename); 24550Sstevel@tonic-gate } else if (strcmp(p_ar->ar_name, "//") == 0) { 24560Sstevel@tonic-gate StringTableList = load_arstring_table( 24570Sstevel@tonic-gate StringTableList, fd, arf, p_ar, 24580Sstevel@tonic-gate filename); 24590Sstevel@tonic-gate cmd = elf_next(arf); 24600Sstevel@tonic-gate (void) elf_end(arf); 24610Sstevel@tonic-gate continue; 24620Sstevel@tonic-gate } else { 24630Sstevel@tonic-gate if (a_flag) { 24640Sstevel@tonic-gate (void) printf("%s[%s]:\n", filename, 24650Sstevel@tonic-gate p_ar->ar_name); 24660Sstevel@tonic-gate if (!p_flag && title == 0) { 24670Sstevel@tonic-gate if (!v_flag) 24680Sstevel@tonic-gate (void) printf( 24690Sstevel@tonic-gate "\n\n\t\t\t***ARCHIVE HEADER***" 24700Sstevel@tonic-gate "\n Date Uid Gid Mode Size Member Name\n\n"); 24710Sstevel@tonic-gate else 24720Sstevel@tonic-gate (void) printf( 24730Sstevel@tonic-gate "\n\n\t\t\t***ARCHIVE HEADER***" 24740Sstevel@tonic-gate "\n Date Uid Gid Mode Size Member Name\n\n"); 24750Sstevel@tonic-gate title = 1; 24760Sstevel@tonic-gate } 24770Sstevel@tonic-gate if (!v_flag) { 24780Sstevel@tonic-gate (void) printf( 24790Sstevel@tonic-gate "\t0x%.8lx %6d %6d 0%.6ho 0x%.8lx %-s\n\n", 24800Sstevel@tonic-gate p_ar->ar_date, 24810Sstevel@tonic-gate (int)p_ar->ar_uid, 24820Sstevel@tonic-gate (int)p_ar->ar_gid, 24830Sstevel@tonic-gate (int)p_ar->ar_mode, 24840Sstevel@tonic-gate p_ar->ar_size, 24850Sstevel@tonic-gate p_ar->ar_name); 24860Sstevel@tonic-gate } else { 24870Sstevel@tonic-gate if ((strftime(buf, DATESIZE, 24880Sstevel@tonic-gate "%b %d %H:%M:%S %Y", 24890Sstevel@tonic-gate localtime( 24900Sstevel@tonic-gate &(p_ar->ar_date)))) == 0) { 24910Sstevel@tonic-gate (void) fprintf(stderr, 24920Sstevel@tonic-gate "%s: %s: don't have enough space to store the date\n", prog_name, filename); 24930Sstevel@tonic-gate exit(1); 24940Sstevel@tonic-gate } 24950Sstevel@tonic-gate (void) printf( 24960Sstevel@tonic-gate "\t%s %6d %6d 0%.6ho 0x%.8lx %-s\n\n", 24970Sstevel@tonic-gate buf, 24980Sstevel@tonic-gate (int)p_ar->ar_uid, 24990Sstevel@tonic-gate (int)p_ar->ar_gid, 25000Sstevel@tonic-gate (int)p_ar->ar_mode, 25010Sstevel@tonic-gate p_ar->ar_size, 25020Sstevel@tonic-gate p_ar->ar_name); 25030Sstevel@tonic-gate } 25040Sstevel@tonic-gate } 25050Sstevel@tonic-gate } 25060Sstevel@tonic-gate cmd = elf_next(arf); 25070Sstevel@tonic-gate (void) elf_end(arf); 25080Sstevel@tonic-gate } /* end while */ 25090Sstevel@tonic-gate 25100Sstevel@tonic-gate err = elf_errno(); 25110Sstevel@tonic-gate if (err != 0) { 25120Sstevel@tonic-gate (void) fprintf(stderr, 25130Sstevel@tonic-gate "%s: %s: %s\n", prog_name, filename, elf_errmsg(err)); 25140Sstevel@tonic-gate } 25150Sstevel@tonic-gate } 25160Sstevel@tonic-gate 25170Sstevel@tonic-gate /* 25180Sstevel@tonic-gate * Process member files of an archive. This function provides 25190Sstevel@tonic-gate * a loop through an archive equivalent the processing of 25200Sstevel@tonic-gate * each_file for individual object files. 25210Sstevel@tonic-gate */ 25220Sstevel@tonic-gate static void 25230Sstevel@tonic-gate dump_ar_files(int fd, Elf *elf_file, char *filename) 25240Sstevel@tonic-gate { 25250Sstevel@tonic-gate Elf_Arhdr *p_ar; 25260Sstevel@tonic-gate Elf *arf; 25270Sstevel@tonic-gate Elf_Cmd cmd; 25280Sstevel@tonic-gate Elf_Kind file_type; 25290Sstevel@tonic-gate GElf_Ehdr elf_head; 25300Sstevel@tonic-gate char *fullname; 25310Sstevel@tonic-gate 25320Sstevel@tonic-gate cmd = ELF_C_READ; 25330Sstevel@tonic-gate while ((arf = elf_begin(fd, cmd, elf_file)) != 0) { 2534*1618Srie size_t len; 2535*1618Srie 25360Sstevel@tonic-gate p_ar = elf_getarhdr(arf); 25370Sstevel@tonic-gate if (p_ar == NULL) { 25380Sstevel@tonic-gate (void) fprintf(stderr, 25390Sstevel@tonic-gate "%s: %s: %s\n", 25400Sstevel@tonic-gate prog_name, filename, elf_errmsg(-1)); 25410Sstevel@tonic-gate return; 25420Sstevel@tonic-gate } 25430Sstevel@tonic-gate if ((strcmp(p_ar->ar_name, "/") == 0) || 25440Sstevel@tonic-gate (strcmp(p_ar->ar_name, "//") == 0)) { 25450Sstevel@tonic-gate cmd = elf_next(arf); 25460Sstevel@tonic-gate (void) elf_end(arf); 25470Sstevel@tonic-gate continue; 25480Sstevel@tonic-gate } 25490Sstevel@tonic-gate 2550*1618Srie len = strlen(filename) + strlen(p_ar->ar_name) + 3; 2551*1618Srie if ((fullname = malloc(len)) == NULL) 2552*1618Srie return; 2553*1618Srie (void) snprintf(fullname, len, "%s[%s]", filename, 2554*1618Srie p_ar->ar_name); 25550Sstevel@tonic-gate (void) printf("\n%s:\n", fullname); 25560Sstevel@tonic-gate file_type = elf_kind(arf); 25570Sstevel@tonic-gate if (file_type == ELF_K_ELF) { 25580Sstevel@tonic-gate if (dump_elf_header(arf, fullname, &elf_head) == NULL) 25590Sstevel@tonic-gate return; 25600Sstevel@tonic-gate if (o_flag) 25610Sstevel@tonic-gate dump_exec_header(arf, 25620Sstevel@tonic-gate (unsigned)elf_head.e_phnum, fullname); 25630Sstevel@tonic-gate if (x_flag) 25640Sstevel@tonic-gate dump_section_table(arf, &elf_head, fullname); 25650Sstevel@tonic-gate } else { 25660Sstevel@tonic-gate (void) fprintf(stderr, 25670Sstevel@tonic-gate "%s: %s: invalid file type\n", 25680Sstevel@tonic-gate prog_name, fullname); 25690Sstevel@tonic-gate cmd = elf_next(arf); 25700Sstevel@tonic-gate (void) elf_end(arf); 25710Sstevel@tonic-gate continue; 25720Sstevel@tonic-gate } 25730Sstevel@tonic-gate 25740Sstevel@tonic-gate cmd = elf_next(arf); 25750Sstevel@tonic-gate (void) elf_end(arf); 25760Sstevel@tonic-gate } /* end while */ 25770Sstevel@tonic-gate } 25780Sstevel@tonic-gate 25790Sstevel@tonic-gate /* 25800Sstevel@tonic-gate * Takes a filename as input. Test first for a valid version 25810Sstevel@tonic-gate * of libelf.a and exit on error. Process each valid file 25820Sstevel@tonic-gate * or archive given as input on the command line. Check 25830Sstevel@tonic-gate * for file type. If it is an archive, process the archive- 25840Sstevel@tonic-gate * specific options first, then files within the archive. 25850Sstevel@tonic-gate * If it is an ELF object file, process it; otherwise 25860Sstevel@tonic-gate * warn that it is an invalid file type. 25870Sstevel@tonic-gate * All options except the archive-specific and program 25880Sstevel@tonic-gate * execution header are processed in the function, dump_section_table. 25890Sstevel@tonic-gate */ 25900Sstevel@tonic-gate static void 25910Sstevel@tonic-gate each_file(char *filename) 25920Sstevel@tonic-gate { 25930Sstevel@tonic-gate Elf *elf_file; 25940Sstevel@tonic-gate GElf_Ehdr elf_head; 25950Sstevel@tonic-gate int fd; 25960Sstevel@tonic-gate Elf_Kind file_type; 25970Sstevel@tonic-gate 25980Sstevel@tonic-gate struct stat buf; 25990Sstevel@tonic-gate 26000Sstevel@tonic-gate Elf_Cmd cmd; 26010Sstevel@tonic-gate errno = 0; 26020Sstevel@tonic-gate 26030Sstevel@tonic-gate if (stat(filename, &buf) == -1) { 2604*1618Srie int err = errno; 2605*1618Srie (void) fprintf(stderr, "%s: %s: %s", prog_name, filename, 2606*1618Srie strerror(err)); 26070Sstevel@tonic-gate return; 26080Sstevel@tonic-gate } 26090Sstevel@tonic-gate 26100Sstevel@tonic-gate if ((fd = open((filename), O_RDONLY)) == -1) { 2611*1618Srie (void) fprintf(stderr, "%s: %s: cannot read\n", prog_name, 2612*1618Srie filename); 26130Sstevel@tonic-gate return; 26140Sstevel@tonic-gate } 26150Sstevel@tonic-gate cmd = ELF_C_READ; 26160Sstevel@tonic-gate if ((elf_file = elf_begin(fd, cmd, (Elf *)0)) == NULL) { 2617*1618Srie (void) fprintf(stderr, "%s: %s: %s\n", prog_name, filename, 2618*1618Srie elf_errmsg(-1)); 26190Sstevel@tonic-gate return; 26200Sstevel@tonic-gate } 26210Sstevel@tonic-gate 26220Sstevel@tonic-gate file_type = elf_kind(elf_file); 26230Sstevel@tonic-gate if (file_type == ELF_K_AR) { 26240Sstevel@tonic-gate if (a_flag || g_flag) { 26250Sstevel@tonic-gate dump_ar_hdr(fd, elf_file, filename); 26260Sstevel@tonic-gate elf_file = elf_begin(fd, cmd, (Elf *)0); 26270Sstevel@tonic-gate } 26280Sstevel@tonic-gate if (z_flag) 26290Sstevel@tonic-gate dump_ar_files(fd, elf_file, filename); 26300Sstevel@tonic-gate } else { 26310Sstevel@tonic-gate if (file_type == ELF_K_ELF) { 26320Sstevel@tonic-gate (void) printf("\n%s:\n", filename); 2633*1618Srie if (dump_elf_header(elf_file, filename, &elf_head)) { 2634*1618Srie if (o_flag) 2635*1618Srie dump_exec_header(elf_file, 2636*1618Srie (unsigned)elf_head.e_phnum, 2637*1618Srie filename); 2638*1618Srie if (x_flag) 2639*1618Srie dump_section_table(elf_file, 2640*1618Srie &elf_head, filename); 26410Sstevel@tonic-gate } 26420Sstevel@tonic-gate } else { 26430Sstevel@tonic-gate (void) fprintf(stderr, "%s: %s: invalid file type\n", 2644*1618Srie prog_name, filename); 26450Sstevel@tonic-gate } 26460Sstevel@tonic-gate } 26470Sstevel@tonic-gate (void) elf_end(elf_file); 26480Sstevel@tonic-gate (void) close(fd); 26490Sstevel@tonic-gate } 26500Sstevel@tonic-gate 26510Sstevel@tonic-gate /* 26520Sstevel@tonic-gate * Sets up flags for command line options given and then 26530Sstevel@tonic-gate * calls each_file() to process each file. 26540Sstevel@tonic-gate */ 26550Sstevel@tonic-gate int 26560Sstevel@tonic-gate main(int argc, char *argv[], char *envp[]) 26570Sstevel@tonic-gate { 26580Sstevel@tonic-gate char *optstr = OPTSTR; /* option string used by getopt() */ 26590Sstevel@tonic-gate int optchar; 26600Sstevel@tonic-gate 26610Sstevel@tonic-gate /* 26620Sstevel@tonic-gate * Check for a binary that better fits this architecture. 26630Sstevel@tonic-gate */ 26640Sstevel@tonic-gate conv_check_native(argv, envp); 26650Sstevel@tonic-gate 26660Sstevel@tonic-gate prog_name = argv[0]; 26670Sstevel@tonic-gate 26680Sstevel@tonic-gate (void) setlocale(LC_ALL, ""); 26690Sstevel@tonic-gate while ((optchar = getopt(argc, argv, optstr)) != -1) { 26700Sstevel@tonic-gate switch (optchar) { 26710Sstevel@tonic-gate case 'a': 26720Sstevel@tonic-gate a_flag = 1; 26730Sstevel@tonic-gate x_flag = 1; 26740Sstevel@tonic-gate break; 26750Sstevel@tonic-gate case 'g': 26760Sstevel@tonic-gate g_flag = 1; 26770Sstevel@tonic-gate x_flag = 1; 26780Sstevel@tonic-gate break; 26790Sstevel@tonic-gate case 'v': 26800Sstevel@tonic-gate v_flag = 1; 26810Sstevel@tonic-gate break; 26820Sstevel@tonic-gate case 'p': 26830Sstevel@tonic-gate p_flag = 1; 26840Sstevel@tonic-gate break; 26850Sstevel@tonic-gate case 'f': 26860Sstevel@tonic-gate f_flag = 1; 26870Sstevel@tonic-gate z_flag = 1; 26880Sstevel@tonic-gate break; 26890Sstevel@tonic-gate case 'o': 26900Sstevel@tonic-gate o_flag = 1; 26910Sstevel@tonic-gate z_flag = 1; 26920Sstevel@tonic-gate break; 26930Sstevel@tonic-gate case 'h': 26940Sstevel@tonic-gate h_flag = 1; 26950Sstevel@tonic-gate x_flag = 1; 26960Sstevel@tonic-gate z_flag = 1; 26970Sstevel@tonic-gate break; 26980Sstevel@tonic-gate case 's': 26990Sstevel@tonic-gate s_flag = 1; 27000Sstevel@tonic-gate x_flag = 1; 27010Sstevel@tonic-gate z_flag = 1; 27020Sstevel@tonic-gate break; 27030Sstevel@tonic-gate case 'd': 27040Sstevel@tonic-gate d_flag = 1; 27050Sstevel@tonic-gate x_flag = 1; 27060Sstevel@tonic-gate z_flag = 1; 27070Sstevel@tonic-gate set_range(optarg, &d_low, &d_hi); 27080Sstevel@tonic-gate break; 27090Sstevel@tonic-gate case 'n': 27100Sstevel@tonic-gate n_flag++; 27110Sstevel@tonic-gate x_flag = 1; 27120Sstevel@tonic-gate z_flag = 1; 27130Sstevel@tonic-gate name = optarg; 27140Sstevel@tonic-gate break; 27150Sstevel@tonic-gate case 'r': 27160Sstevel@tonic-gate r_flag = 1; 27170Sstevel@tonic-gate x_flag = 1; 27180Sstevel@tonic-gate z_flag = 1; 27190Sstevel@tonic-gate break; 27200Sstevel@tonic-gate case 't': 27210Sstevel@tonic-gate t_flag = 1; 27220Sstevel@tonic-gate x_flag = 1; 27230Sstevel@tonic-gate z_flag = 1; 27240Sstevel@tonic-gate break; 27250Sstevel@tonic-gate case 'C': 27260Sstevel@tonic-gate C_flag = 1; 27270Sstevel@tonic-gate t_flag = 1; 27280Sstevel@tonic-gate x_flag = 1; 27290Sstevel@tonic-gate z_flag = 1; 27300Sstevel@tonic-gate break; 27310Sstevel@tonic-gate case 'T': 27320Sstevel@tonic-gate T_flag = 1; 27330Sstevel@tonic-gate x_flag = 1; 27340Sstevel@tonic-gate z_flag = 1; 27350Sstevel@tonic-gate set_range(optarg, &T_low, &T_hi); 27360Sstevel@tonic-gate break; 27370Sstevel@tonic-gate case 'c': 27380Sstevel@tonic-gate c_flag = 1; 27390Sstevel@tonic-gate x_flag = 1; 27400Sstevel@tonic-gate z_flag = 1; 27410Sstevel@tonic-gate break; 27420Sstevel@tonic-gate case 'L': 27430Sstevel@tonic-gate L_flag = 1; 27440Sstevel@tonic-gate x_flag = 1; 27450Sstevel@tonic-gate z_flag = 1; 27460Sstevel@tonic-gate break; 27470Sstevel@tonic-gate case 'V': 27480Sstevel@tonic-gate V_flag = 1; 27490Sstevel@tonic-gate (void) fprintf(stderr, "dump: %s %s\n", 27500Sstevel@tonic-gate (const char *)SGU_PKG, 27510Sstevel@tonic-gate (const char *)SGU_REL); 27520Sstevel@tonic-gate break; 27530Sstevel@tonic-gate case '?': 27540Sstevel@tonic-gate errflag += 1; 27550Sstevel@tonic-gate break; 27560Sstevel@tonic-gate default: 27570Sstevel@tonic-gate break; 27580Sstevel@tonic-gate } 27590Sstevel@tonic-gate } 27600Sstevel@tonic-gate 27610Sstevel@tonic-gate if (errflag || (optind >= argc) || (!z_flag && !x_flag)) { 27620Sstevel@tonic-gate if (!(V_flag && (argc == 2))) { 27630Sstevel@tonic-gate usage(); 27640Sstevel@tonic-gate exit(269); 27650Sstevel@tonic-gate } 27660Sstevel@tonic-gate } 27670Sstevel@tonic-gate 2768*1618Srie if (elf_version(EV_CURRENT) == EV_NONE) { 2769*1618Srie (void) fprintf(stderr, "%s: libelf is out of date\n", 2770*1618Srie prog_name); 2771*1618Srie exit(101); 2772*1618Srie } 2773*1618Srie 27740Sstevel@tonic-gate while (optind < argc) { 27750Sstevel@tonic-gate each_file(argv[optind]); 27760Sstevel@tonic-gate optind++; 27770Sstevel@tonic-gate } 27780Sstevel@tonic-gate return (0); 27790Sstevel@tonic-gate } 2780