1*0Sstevel@tonic-gate /* 2*0Sstevel@tonic-gate * CDDL HEADER START 3*0Sstevel@tonic-gate * 4*0Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*0Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*0Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*0Sstevel@tonic-gate * with the License. 8*0Sstevel@tonic-gate * 9*0Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*0Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*0Sstevel@tonic-gate * See the License for the specific language governing permissions 12*0Sstevel@tonic-gate * and limitations under the License. 13*0Sstevel@tonic-gate * 14*0Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*0Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*0Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*0Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*0Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*0Sstevel@tonic-gate * 20*0Sstevel@tonic-gate * CDDL HEADER END 21*0Sstevel@tonic-gate */ 22*0Sstevel@tonic-gate /* 23*0Sstevel@tonic-gate * Copyright (c) 1988 AT&T 24*0Sstevel@tonic-gate * All Rights Reserved 25*0Sstevel@tonic-gate * 26*0Sstevel@tonic-gate */ 27*0Sstevel@tonic-gate 28*0Sstevel@tonic-gate /* 29*0Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 30*0Sstevel@tonic-gate * Use is subject to license terms. 31*0Sstevel@tonic-gate */ 32*0Sstevel@tonic-gate 33*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 34*0Sstevel@tonic-gate 35*0Sstevel@tonic-gate #include <stdio.h> 36*0Sstevel@tonic-gate #include <stdlib.h> 37*0Sstevel@tonic-gate #include <locale.h> 38*0Sstevel@tonic-gate #include <unistd.h> 39*0Sstevel@tonic-gate #include <libelf.h> 40*0Sstevel@tonic-gate #include <link.h> 41*0Sstevel@tonic-gate #include <sys/elf_M32.h> 42*0Sstevel@tonic-gate #include <sys/elf_386.h> 43*0Sstevel@tonic-gate #include <sys/elf_SPARC.h> 44*0Sstevel@tonic-gate #include <sys/machelf.h> 45*0Sstevel@tonic-gate #include <fcntl.h> 46*0Sstevel@tonic-gate #include <sys/stat.h> 47*0Sstevel@tonic-gate #include <errno.h> 48*0Sstevel@tonic-gate #include <string.h> 49*0Sstevel@tonic-gate #include "sgs.h" 50*0Sstevel@tonic-gate #include "conv.h" 51*0Sstevel@tonic-gate #include "dump.h" 52*0Sstevel@tonic-gate 53*0Sstevel@tonic-gate 54*0Sstevel@tonic-gate #define OPTSTR "agcd:fhn:oprstvCLT:V?" /* option string for getopt() */ 55*0Sstevel@tonic-gate 56*0Sstevel@tonic-gate const char *UNKNOWN = "<unknown>"; 57*0Sstevel@tonic-gate 58*0Sstevel@tonic-gate static SCNTAB *p_symtab, *p_head_scns, *p_dynsym; 59*0Sstevel@tonic-gate 60*0Sstevel@tonic-gate static int 61*0Sstevel@tonic-gate x_flag = 0, /* option requires section header table */ 62*0Sstevel@tonic-gate z_flag = 0, /* process files within an archive */ 63*0Sstevel@tonic-gate rn_flag = 0; /* dump named relocation information */ 64*0Sstevel@tonic-gate 65*0Sstevel@tonic-gate static int 66*0Sstevel@tonic-gate /* flags: ?_flag corresponds to ? option */ 67*0Sstevel@tonic-gate a_flag = 0, /* dump archive header of each member of archive */ 68*0Sstevel@tonic-gate g_flag = 0, /* dump archive symbol table */ 69*0Sstevel@tonic-gate c_flag = 0, /* dump the string table */ 70*0Sstevel@tonic-gate d_flag = 0, /* dump range of sections */ 71*0Sstevel@tonic-gate f_flag = 0, /* dump each file header */ 72*0Sstevel@tonic-gate h_flag = 0, /* dump section headers */ 73*0Sstevel@tonic-gate n_flag = 0, /* dump named section */ 74*0Sstevel@tonic-gate o_flag = 0, /* dump each program execution header */ 75*0Sstevel@tonic-gate r_flag = 0, /* dump relocation information */ 76*0Sstevel@tonic-gate s_flag = 0, /* dump section contents */ 77*0Sstevel@tonic-gate t_flag = 0, /* dump symbol table entries */ 78*0Sstevel@tonic-gate C_flag = 0, /* dump decoded C++ symbol names */ 79*0Sstevel@tonic-gate L_flag = 0, /* dump dynamic linking information */ 80*0Sstevel@tonic-gate T_flag = 0, /* dump symbol table range */ 81*0Sstevel@tonic-gate V_flag = 0; /* dump version information */ 82*0Sstevel@tonic-gate 83*0Sstevel@tonic-gate int p_flag = 0, /* suppress printing of headings */ 84*0Sstevel@tonic-gate v_flag = 0; /* print information in verbose form */ 85*0Sstevel@tonic-gate 86*0Sstevel@tonic-gate static int 87*0Sstevel@tonic-gate d_low = 0, /* range for use with -d */ 88*0Sstevel@tonic-gate d_hi = 0, 89*0Sstevel@tonic-gate d_num = 0; 90*0Sstevel@tonic-gate 91*0Sstevel@tonic-gate static int 92*0Sstevel@tonic-gate T_low = 0, /* range for use with -T */ 93*0Sstevel@tonic-gate T_hi = 0, 94*0Sstevel@tonic-gate T_num = 0; 95*0Sstevel@tonic-gate 96*0Sstevel@tonic-gate static char *name = NULL; /* for use with -n option */ 97*0Sstevel@tonic-gate char *prog_name; 98*0Sstevel@tonic-gate static int errflag = 0; 99*0Sstevel@tonic-gate 100*0Sstevel@tonic-gate static struct stab_list_s { 101*0Sstevel@tonic-gate struct stab_list_s *next; 102*0Sstevel@tonic-gate char *strings; 103*0Sstevel@tonic-gate size_t size; 104*0Sstevel@tonic-gate } *StringTableList = (void *)0; 105*0Sstevel@tonic-gate 106*0Sstevel@tonic-gate extern void ar_sym_read(); 107*0Sstevel@tonic-gate extern void dump_exec_header(); 108*0Sstevel@tonic-gate 109*0Sstevel@tonic-gate 110*0Sstevel@tonic-gate /* 111*0Sstevel@tonic-gate * Get the section descriptor and set the size of the 112*0Sstevel@tonic-gate * data returned. Data is byte-order converted. 113*0Sstevel@tonic-gate */ 114*0Sstevel@tonic-gate void * 115*0Sstevel@tonic-gate get_scndata(Elf_Scn *fd_scn, size_t *size) 116*0Sstevel@tonic-gate { 117*0Sstevel@tonic-gate Elf_Data *p_data; 118*0Sstevel@tonic-gate 119*0Sstevel@tonic-gate p_data = 0; 120*0Sstevel@tonic-gate if ((p_data = elf_getdata(fd_scn, p_data)) == 0 || 121*0Sstevel@tonic-gate p_data->d_size == 0) { 122*0Sstevel@tonic-gate return (NULL); 123*0Sstevel@tonic-gate } 124*0Sstevel@tonic-gate *size = p_data->d_size; 125*0Sstevel@tonic-gate return (p_data->d_buf); 126*0Sstevel@tonic-gate } 127*0Sstevel@tonic-gate 128*0Sstevel@tonic-gate /* 129*0Sstevel@tonic-gate * Get the section descriptor and set the size of the 130*0Sstevel@tonic-gate * data returned. Data is raw (i.e., not byte-order converted). 131*0Sstevel@tonic-gate */ 132*0Sstevel@tonic-gate static void * 133*0Sstevel@tonic-gate get_rawscn(Elf_Scn *fd_scn, size_t *size) 134*0Sstevel@tonic-gate { 135*0Sstevel@tonic-gate Elf_Data *p_data; 136*0Sstevel@tonic-gate 137*0Sstevel@tonic-gate p_data = 0; 138*0Sstevel@tonic-gate if ((p_data = elf_rawdata(fd_scn, p_data)) == 0 || 139*0Sstevel@tonic-gate p_data->d_size == 0) { 140*0Sstevel@tonic-gate return (NULL); 141*0Sstevel@tonic-gate } 142*0Sstevel@tonic-gate 143*0Sstevel@tonic-gate *size = p_data->d_size; 144*0Sstevel@tonic-gate return (p_data->d_buf); 145*0Sstevel@tonic-gate } 146*0Sstevel@tonic-gate 147*0Sstevel@tonic-gate /* 148*0Sstevel@tonic-gate * Print out a usage message in short form when program is invoked 149*0Sstevel@tonic-gate * with insufficient or no arguments, and in long form when given 150*0Sstevel@tonic-gate * either a ? or an invalid option. 151*0Sstevel@tonic-gate */ 152*0Sstevel@tonic-gate static void 153*0Sstevel@tonic-gate usage() 154*0Sstevel@tonic-gate { 155*0Sstevel@tonic-gate (void) fprintf(stderr, 156*0Sstevel@tonic-gate "Usage: %s [-%s] file(s) ...\n", prog_name, OPTSTR); 157*0Sstevel@tonic-gate if (errflag) { 158*0Sstevel@tonic-gate (void) fprintf(stderr, 159*0Sstevel@tonic-gate "\t\t[-a dump archive header of each member of archive]\n\ 160*0Sstevel@tonic-gate [-g dump archive global symbol table]\n\ 161*0Sstevel@tonic-gate [-c dump the string table]\n\ 162*0Sstevel@tonic-gate [-d dump range of sections]\n\ 163*0Sstevel@tonic-gate [-f dump each file header]\n\ 164*0Sstevel@tonic-gate [-h dump section headers]\n\ 165*0Sstevel@tonic-gate [-n dump named section]\n\ 166*0Sstevel@tonic-gate [-o dump each program execution header]\n\ 167*0Sstevel@tonic-gate [-p suppress printing of headings]\n\ 168*0Sstevel@tonic-gate [-r dump relocation information]\n\ 169*0Sstevel@tonic-gate [-s dump section contents]\n\ 170*0Sstevel@tonic-gate [-t dump symbol table entries]\n\ 171*0Sstevel@tonic-gate [-v print information in verbose form]\n\ 172*0Sstevel@tonic-gate [-C dump decoded C++ symbol names]\n\ 173*0Sstevel@tonic-gate [-L dump the .dynamic structure]\n\ 174*0Sstevel@tonic-gate [-T dump symbol table range]\n\ 175*0Sstevel@tonic-gate [-V dump version information]\n"); 176*0Sstevel@tonic-gate } 177*0Sstevel@tonic-gate } 178*0Sstevel@tonic-gate 179*0Sstevel@tonic-gate /* 180*0Sstevel@tonic-gate * Set a range. Input is a character string, a lower 181*0Sstevel@tonic-gate * bound and an upper bound. This function converts 182*0Sstevel@tonic-gate * a character string into its correct integer values, 183*0Sstevel@tonic-gate * setting the first value as the lower bound, and 184*0Sstevel@tonic-gate * the second value as the upper bound. If more values 185*0Sstevel@tonic-gate * are given they are ignored with a warning. 186*0Sstevel@tonic-gate */ 187*0Sstevel@tonic-gate static void 188*0Sstevel@tonic-gate set_range(char *s, int *low, int *high) 189*0Sstevel@tonic-gate { 190*0Sstevel@tonic-gate char *w; 191*0Sstevel@tonic-gate char *lasts; 192*0Sstevel@tonic-gate 193*0Sstevel@tonic-gate while ((w = strtok_r(s, ",", &lasts)) != NULL) { 194*0Sstevel@tonic-gate if (!(*low)) 195*0Sstevel@tonic-gate /* LINTED */ 196*0Sstevel@tonic-gate *low = (int)atol(w); 197*0Sstevel@tonic-gate else 198*0Sstevel@tonic-gate if (!(*high)) 199*0Sstevel@tonic-gate /* LINTED */ 200*0Sstevel@tonic-gate *high = (int)atol(w); 201*0Sstevel@tonic-gate else { 202*0Sstevel@tonic-gate (void) fprintf(stderr, 203*0Sstevel@tonic-gate "%s: too many arguments - %s ignored\n", 204*0Sstevel@tonic-gate prog_name, w); 205*0Sstevel@tonic-gate return; 206*0Sstevel@tonic-gate } 207*0Sstevel@tonic-gate s = NULL; 208*0Sstevel@tonic-gate } /* end while */ 209*0Sstevel@tonic-gate } 210*0Sstevel@tonic-gate 211*0Sstevel@tonic-gate 212*0Sstevel@tonic-gate /* 213*0Sstevel@tonic-gate * Print static shared library information. 214*0Sstevel@tonic-gate */ 215*0Sstevel@tonic-gate static void 216*0Sstevel@tonic-gate print_static(SCNTAB *l_scns, char *filename) 217*0Sstevel@tonic-gate { 218*0Sstevel@tonic-gate size_t section_size; 219*0Sstevel@tonic-gate unsigned char *strtab; 220*0Sstevel@tonic-gate unsigned char *path, buf[1024]; 221*0Sstevel@tonic-gate unsigned long *temp; 222*0Sstevel@tonic-gate unsigned long total, topath; 223*0Sstevel@tonic-gate 224*0Sstevel@tonic-gate (void) printf("\n **** STATIC SHARED LIBRARY INFORMATION ****\n"); 225*0Sstevel@tonic-gate (void) printf("\n%s:\n", filename); 226*0Sstevel@tonic-gate (void) printf("\t"); 227*0Sstevel@tonic-gate section_size = 0; 228*0Sstevel@tonic-gate if ((strtab = (unsigned char *) 229*0Sstevel@tonic-gate get_scndata(l_scns->p_sd, §ion_size)) == NULL) { 230*0Sstevel@tonic-gate return; 231*0Sstevel@tonic-gate } 232*0Sstevel@tonic-gate 233*0Sstevel@tonic-gate while (section_size != 0) { 234*0Sstevel@tonic-gate /* LINTED */ 235*0Sstevel@tonic-gate temp = (unsigned long *)strtab; 236*0Sstevel@tonic-gate total = temp[0]; 237*0Sstevel@tonic-gate topath = temp[1]; 238*0Sstevel@tonic-gate path = strtab + (topath*sizeof (long)); 239*0Sstevel@tonic-gate (void) strncpy((char *)buf, (char *)path, 240*0Sstevel@tonic-gate (total - topath)*sizeof (long)); 241*0Sstevel@tonic-gate (void) fprintf(stdout, "%s\n", buf); 242*0Sstevel@tonic-gate strtab += total*sizeof (long); 243*0Sstevel@tonic-gate section_size -= (total*sizeof (long)); 244*0Sstevel@tonic-gate } 245*0Sstevel@tonic-gate } 246*0Sstevel@tonic-gate 247*0Sstevel@tonic-gate /* 248*0Sstevel@tonic-gate * Print raw data in hexidecimal. Input is the section data to 249*0Sstevel@tonic-gate * be printed out and the size of the data. Output is relative 250*0Sstevel@tonic-gate * to a table lookup in dumpmap.h. 251*0Sstevel@tonic-gate */ 252*0Sstevel@tonic-gate static void 253*0Sstevel@tonic-gate print_rawdata(unsigned char *p_sec, size_t size) 254*0Sstevel@tonic-gate { 255*0Sstevel@tonic-gate size_t j; 256*0Sstevel@tonic-gate size_t count; 257*0Sstevel@tonic-gate 258*0Sstevel@tonic-gate count = 1; 259*0Sstevel@tonic-gate 260*0Sstevel@tonic-gate (void) printf("\t"); 261*0Sstevel@tonic-gate for (j = size/sizeof (short); j != 0; --j, ++count) { 262*0Sstevel@tonic-gate (void) printf("%.2x %.2x ", p_sec[0], p_sec[1]); 263*0Sstevel@tonic-gate p_sec += 2; 264*0Sstevel@tonic-gate if (count == 12) { 265*0Sstevel@tonic-gate (void) printf("\n\t"); 266*0Sstevel@tonic-gate count = 0; 267*0Sstevel@tonic-gate } 268*0Sstevel@tonic-gate } 269*0Sstevel@tonic-gate 270*0Sstevel@tonic-gate /* 271*0Sstevel@tonic-gate * take care of last byte if odd byte section 272*0Sstevel@tonic-gate */ 273*0Sstevel@tonic-gate if ((size & 0x1L) == 1L) 274*0Sstevel@tonic-gate (void) printf("%.2x", *p_sec); 275*0Sstevel@tonic-gate (void) printf("\n"); 276*0Sstevel@tonic-gate } 277*0Sstevel@tonic-gate 278*0Sstevel@tonic-gate 279*0Sstevel@tonic-gate 280*0Sstevel@tonic-gate /* 281*0Sstevel@tonic-gate * Print relocation data of type SHT_RELA 282*0Sstevel@tonic-gate * If d_flag, print data corresponding only to 283*0Sstevel@tonic-gate * the section or range of sections specified. 284*0Sstevel@tonic-gate * If n_flag, print data corresponding only to 285*0Sstevel@tonic-gate * the named section. 286*0Sstevel@tonic-gate */ 287*0Sstevel@tonic-gate static void 288*0Sstevel@tonic-gate print_rela(Elf *elf_file, SCNTAB *p_scns, Elf_Data *rdata, Elf_Data *sym_data, 289*0Sstevel@tonic-gate GElf_Ehdr * p_ehdr, size_t reloc_size, size_t sym_size, char *filename, 290*0Sstevel@tonic-gate SCNTAB *reloc_symtab) 291*0Sstevel@tonic-gate { 292*0Sstevel@tonic-gate GElf_Rela rela; 293*0Sstevel@tonic-gate GElf_Sym sym; 294*0Sstevel@tonic-gate size_t no_entries; 295*0Sstevel@tonic-gate size_t rel_entsize; 296*0Sstevel@tonic-gate size_t no_syms; 297*0Sstevel@tonic-gate int type, symid; 298*0Sstevel@tonic-gate static int n_title = 0; 299*0Sstevel@tonic-gate int ndx = 0; 300*0Sstevel@tonic-gate char *sym_name; 301*0Sstevel@tonic-gate int adj = 0; 302*0Sstevel@tonic-gate 303*0Sstevel@tonic-gate if (gelf_getclass(elf_file) == ELFCLASS64) 304*0Sstevel@tonic-gate adj = 4; 305*0Sstevel@tonic-gate 306*0Sstevel@tonic-gate rel_entsize = p_scns->p_shdr.sh_entsize; 307*0Sstevel@tonic-gate if ((rel_entsize == 0) || 308*0Sstevel@tonic-gate (rel_entsize > p_scns->p_shdr.sh_size)) { 309*0Sstevel@tonic-gate rel_entsize = gelf_fsize(elf_file, ELF_T_RELA, 1, 310*0Sstevel@tonic-gate EV_CURRENT); 311*0Sstevel@tonic-gate } 312*0Sstevel@tonic-gate no_entries = reloc_size / rel_entsize; 313*0Sstevel@tonic-gate 314*0Sstevel@tonic-gate no_syms = sym_size / gelf_fsize(elf_file, ELF_T_SYM, 1, EV_CURRENT); 315*0Sstevel@tonic-gate while (no_entries--) { 316*0Sstevel@tonic-gate (void) gelf_getrela(rdata, ndx, &rela); 317*0Sstevel@tonic-gate /* LINTED */ 318*0Sstevel@tonic-gate type = (int)GELF_R_TYPE(rela.r_info); 319*0Sstevel@tonic-gate /* LINTED */ 320*0Sstevel@tonic-gate symid = (int)GELF_R_SYM(rela.r_info); 321*0Sstevel@tonic-gate /* LINTED */ 322*0Sstevel@tonic-gate if ((symid > (no_syms - 1)) || (symid < 0)) { 323*0Sstevel@tonic-gate (void) fprintf(stderr, "%s: %s: invalid symbol table " 324*0Sstevel@tonic-gate "offset - %d - in %s\n", prog_name, filename, 325*0Sstevel@tonic-gate symid, p_scns->scn_name); 326*0Sstevel@tonic-gate ndx++; 327*0Sstevel@tonic-gate continue; 328*0Sstevel@tonic-gate } 329*0Sstevel@tonic-gate (void) gelf_getsym(sym_data, symid, &sym); 330*0Sstevel@tonic-gate sym_name = (char *)elf_strptr(elf_file, 331*0Sstevel@tonic-gate reloc_symtab->p_shdr.sh_link, sym.st_name); 332*0Sstevel@tonic-gate if (sym_name == NULL) 333*0Sstevel@tonic-gate sym_name = (char *)UNKNOWN; 334*0Sstevel@tonic-gate if (r_flag && rn_flag) { 335*0Sstevel@tonic-gate if (strcmp(name, p_scns->scn_name) != 0) { 336*0Sstevel@tonic-gate ndx++; 337*0Sstevel@tonic-gate continue; 338*0Sstevel@tonic-gate } 339*0Sstevel@tonic-gate if (!n_title) { 340*0Sstevel@tonic-gate (void) printf("\n%s:\n", p_scns->scn_name); 341*0Sstevel@tonic-gate (void) printf("%-*s%-*s%-*s%s\n\n", 342*0Sstevel@tonic-gate 12 + adj, "Offset", 22, "Symndx", 343*0Sstevel@tonic-gate 16, "Type", "Addend"); 344*0Sstevel@tonic-gate n_title = 1; 345*0Sstevel@tonic-gate } 346*0Sstevel@tonic-gate } 347*0Sstevel@tonic-gate if (d_flag) { 348*0Sstevel@tonic-gate if (!d_hi) 349*0Sstevel@tonic-gate d_hi = d_low; 350*0Sstevel@tonic-gate if ((symid < d_low) || (symid > d_hi)) { 351*0Sstevel@tonic-gate ndx++; 352*0Sstevel@tonic-gate continue; 353*0Sstevel@tonic-gate } 354*0Sstevel@tonic-gate } 355*0Sstevel@tonic-gate 356*0Sstevel@tonic-gate (void) printf("%-#*llx", 12 + adj, EC_XWORD(rela.r_offset)); 357*0Sstevel@tonic-gate if (!v_flag) { 358*0Sstevel@tonic-gate (void) printf("%-22d%-18d", symid, type); 359*0Sstevel@tonic-gate } else { 360*0Sstevel@tonic-gate if (strlen(sym_name)) { 361*0Sstevel@tonic-gate size_t len = strlen(sym_name) + 1; 362*0Sstevel@tonic-gate char tmpstr[10]; 363*0Sstevel@tonic-gate if (len > 22) { 364*0Sstevel@tonic-gate (void) sprintf(tmpstr, "%%-%ds", 365*0Sstevel@tonic-gate /* LINTED */ 366*0Sstevel@tonic-gate (int)len); 367*0Sstevel@tonic-gate (void) printf(tmpstr, sym_name); 368*0Sstevel@tonic-gate } else 369*0Sstevel@tonic-gate (void) printf("%-22s", sym_name); 370*0Sstevel@tonic-gate } else 371*0Sstevel@tonic-gate (void) printf("%-22d", symid); 372*0Sstevel@tonic-gate print_reloc_type(p_ehdr->e_machine, type); 373*0Sstevel@tonic-gate } 374*0Sstevel@tonic-gate (void) printf("%lld\n", EC_SXWORD(rela.r_addend)); 375*0Sstevel@tonic-gate ndx++; 376*0Sstevel@tonic-gate } 377*0Sstevel@tonic-gate } 378*0Sstevel@tonic-gate 379*0Sstevel@tonic-gate /* 380*0Sstevel@tonic-gate * Print relocation data of type SHT_REL. 381*0Sstevel@tonic-gate * If d_flag, print data corresponding only to 382*0Sstevel@tonic-gate * the section or range of sections specified. 383*0Sstevel@tonic-gate * If n_flag, print data corresponding only to 384*0Sstevel@tonic-gate * the named section. 385*0Sstevel@tonic-gate */ 386*0Sstevel@tonic-gate static void 387*0Sstevel@tonic-gate print_rel(Elf *elf_file, SCNTAB *p_scns, Elf_Data *rdata, Elf_Data *sym_data, 388*0Sstevel@tonic-gate GElf_Ehdr *p_ehdr, size_t reloc_size, size_t sym_size, char *filename, 389*0Sstevel@tonic-gate SCNTAB *reloc_symtab) 390*0Sstevel@tonic-gate { 391*0Sstevel@tonic-gate GElf_Rel rel; 392*0Sstevel@tonic-gate GElf_Sym sym; 393*0Sstevel@tonic-gate size_t no_entries; 394*0Sstevel@tonic-gate size_t rel_entsize; 395*0Sstevel@tonic-gate int type, symid; 396*0Sstevel@tonic-gate size_t no_syms; 397*0Sstevel@tonic-gate static int n_title = 0; 398*0Sstevel@tonic-gate int ndx = 0; 399*0Sstevel@tonic-gate char *sym_name; 400*0Sstevel@tonic-gate int adj = 0; 401*0Sstevel@tonic-gate 402*0Sstevel@tonic-gate if (gelf_getclass(elf_file) == ELFCLASS64) 403*0Sstevel@tonic-gate adj = 4; 404*0Sstevel@tonic-gate 405*0Sstevel@tonic-gate rel_entsize = p_scns->p_shdr.sh_entsize; 406*0Sstevel@tonic-gate if ((rel_entsize == 0) || 407*0Sstevel@tonic-gate (rel_entsize > p_scns->p_shdr.sh_size)) { 408*0Sstevel@tonic-gate rel_entsize = gelf_fsize(elf_file, ELF_T_REL, 1, 409*0Sstevel@tonic-gate EV_CURRENT); 410*0Sstevel@tonic-gate } 411*0Sstevel@tonic-gate no_entries = reloc_size / rel_entsize; 412*0Sstevel@tonic-gate 413*0Sstevel@tonic-gate no_syms = sym_size / gelf_fsize(elf_file, ELF_T_SYM, 1, EV_CURRENT); 414*0Sstevel@tonic-gate while (no_entries--) { 415*0Sstevel@tonic-gate (void) gelf_getrel(rdata, ndx, &rel); 416*0Sstevel@tonic-gate /* LINTED */ 417*0Sstevel@tonic-gate type = (int)GELF_R_TYPE(rel.r_info); 418*0Sstevel@tonic-gate /* LINTED */ 419*0Sstevel@tonic-gate symid = (int)GELF_R_SYM(rel.r_info); 420*0Sstevel@tonic-gate /* LINTED */ 421*0Sstevel@tonic-gate if ((symid > (no_syms - 1)) || (symid < 0)) { 422*0Sstevel@tonic-gate (void) fprintf(stderr, "%s: %s: invalid symbol table " 423*0Sstevel@tonic-gate "offset - %d - in %s\n", prog_name, filename, 424*0Sstevel@tonic-gate symid, p_scns->scn_name); 425*0Sstevel@tonic-gate ndx++; 426*0Sstevel@tonic-gate continue; 427*0Sstevel@tonic-gate } 428*0Sstevel@tonic-gate (void) gelf_getsym(sym_data, symid, &sym); 429*0Sstevel@tonic-gate sym_name = (char *)elf_strptr(elf_file, 430*0Sstevel@tonic-gate reloc_symtab->p_shdr.sh_link, sym.st_name); 431*0Sstevel@tonic-gate if (sym_name == NULL) 432*0Sstevel@tonic-gate sym_name = (char *)UNKNOWN; 433*0Sstevel@tonic-gate if (r_flag && rn_flag) { 434*0Sstevel@tonic-gate if (strcmp(name, p_scns->scn_name) != 0) { 435*0Sstevel@tonic-gate ndx++; 436*0Sstevel@tonic-gate continue; 437*0Sstevel@tonic-gate } 438*0Sstevel@tonic-gate if (!n_title) { 439*0Sstevel@tonic-gate (void) printf("\n%s:\n", p_scns->scn_name); 440*0Sstevel@tonic-gate (void) printf("%-*s%-*s%s\n\n", 441*0Sstevel@tonic-gate 12 + adj, "Offset", 20, "Symndx", "Type"); 442*0Sstevel@tonic-gate n_title = 1; 443*0Sstevel@tonic-gate } 444*0Sstevel@tonic-gate } 445*0Sstevel@tonic-gate if (d_flag) { 446*0Sstevel@tonic-gate if (!d_hi) 447*0Sstevel@tonic-gate d_hi = d_low; 448*0Sstevel@tonic-gate if ((symid < d_low) || (symid > d_hi)) { 449*0Sstevel@tonic-gate ndx++; 450*0Sstevel@tonic-gate continue; 451*0Sstevel@tonic-gate } 452*0Sstevel@tonic-gate } 453*0Sstevel@tonic-gate 454*0Sstevel@tonic-gate (void) printf("%-#*llx", 12 + adj, EC_ADDR(rel.r_offset)); 455*0Sstevel@tonic-gate if (!v_flag) { 456*0Sstevel@tonic-gate (void) printf("%-20d%-18d", symid, type); 457*0Sstevel@tonic-gate } else { 458*0Sstevel@tonic-gate if (strlen(sym_name)) 459*0Sstevel@tonic-gate (void) printf("%-20s", sym_name); 460*0Sstevel@tonic-gate else 461*0Sstevel@tonic-gate (void) printf("%-20d", sym.st_name); 462*0Sstevel@tonic-gate 463*0Sstevel@tonic-gate print_reloc_type(p_ehdr->e_machine, type); 464*0Sstevel@tonic-gate } 465*0Sstevel@tonic-gate (void) printf("\n"); 466*0Sstevel@tonic-gate ndx++; 467*0Sstevel@tonic-gate } 468*0Sstevel@tonic-gate } 469*0Sstevel@tonic-gate 470*0Sstevel@tonic-gate /* demangle C++ names */ 471*0Sstevel@tonic-gate static char *format = "%s\t[%s]"; 472*0Sstevel@tonic-gate static char * 473*0Sstevel@tonic-gate demangled_name(char *s) 474*0Sstevel@tonic-gate { 475*0Sstevel@tonic-gate char *dn; 476*0Sstevel@tonic-gate static char *buf; 477*0Sstevel@tonic-gate 478*0Sstevel@tonic-gate dn = sgs_demangle(s); 479*0Sstevel@tonic-gate 480*0Sstevel@tonic-gate /* 481*0Sstevel@tonic-gate * If not demangled, just return the symbol name 482*0Sstevel@tonic-gate */ 483*0Sstevel@tonic-gate if (strcmp(s, dn) == 0) 484*0Sstevel@tonic-gate return (s); 485*0Sstevel@tonic-gate 486*0Sstevel@tonic-gate /* 487*0Sstevel@tonic-gate * Demangled. Format it 488*0Sstevel@tonic-gate */ 489*0Sstevel@tonic-gate if (buf != NULL) 490*0Sstevel@tonic-gate free(buf); 491*0Sstevel@tonic-gate 492*0Sstevel@tonic-gate buf = malloc(strlen(dn) + 1 + 1 + strlen(s) + 1 + 1); 493*0Sstevel@tonic-gate if (buf == NULL) 494*0Sstevel@tonic-gate return (s); 495*0Sstevel@tonic-gate 496*0Sstevel@tonic-gate (void) sprintf(buf, format, dn, s); 497*0Sstevel@tonic-gate return (buf); 498*0Sstevel@tonic-gate } 499*0Sstevel@tonic-gate 500*0Sstevel@tonic-gate /* 501*0Sstevel@tonic-gate * Print the symbol table. Input is an ELF file descriptor, a 502*0Sstevel@tonic-gate * pointer to the symbol table SCNTAB structure, 503*0Sstevel@tonic-gate * the number of symbols, a range of symbols to print, 504*0Sstevel@tonic-gate * an index which is the number of the 505*0Sstevel@tonic-gate * section in the file, and the filename. The number of sections, 506*0Sstevel@tonic-gate * the range, and the index are set in 507*0Sstevel@tonic-gate * dump_symbol_table, depending on whether -n or -T were set. 508*0Sstevel@tonic-gate */ 509*0Sstevel@tonic-gate static void 510*0Sstevel@tonic-gate print_symtab(Elf *elf_file, SCNTAB *p_symtab, Elf_Data *sym_data, 511*0Sstevel@tonic-gate long range, int index) 512*0Sstevel@tonic-gate { 513*0Sstevel@tonic-gate GElf_Sym sym; 514*0Sstevel@tonic-gate int adj = 0; /* field adjustment for elf64 */ 515*0Sstevel@tonic-gate Elf32_Word *symshndx = 0; 516*0Sstevel@tonic-gate unsigned int nosymshndx = 0; 517*0Sstevel@tonic-gate 518*0Sstevel@tonic-gate if (gelf_getclass(elf_file) == ELFCLASS64) 519*0Sstevel@tonic-gate adj = 4; 520*0Sstevel@tonic-gate 521*0Sstevel@tonic-gate while (range > 0) { 522*0Sstevel@tonic-gate char *sym_name = (char *)0; 523*0Sstevel@tonic-gate int type, bind; 524*0Sstevel@tonic-gate int specsec; 525*0Sstevel@tonic-gate unsigned int shndx; 526*0Sstevel@tonic-gate 527*0Sstevel@tonic-gate (void) gelf_getsym(sym_data, index, &sym); 528*0Sstevel@tonic-gate type = (int)GELF_ST_TYPE(sym.st_info); 529*0Sstevel@tonic-gate bind = (int)GELF_ST_BIND(sym.st_info); 530*0Sstevel@tonic-gate 531*0Sstevel@tonic-gate if ((sym.st_shndx == SHN_XINDEX) && 532*0Sstevel@tonic-gate (symshndx == 0) && (nosymshndx == 0)) { 533*0Sstevel@tonic-gate Elf_Scn *_scn; 534*0Sstevel@tonic-gate GElf_Shdr _shdr; 535*0Sstevel@tonic-gate size_t symscnndx; 536*0Sstevel@tonic-gate 537*0Sstevel@tonic-gate symscnndx = elf_ndxscn(p_symtab->p_sd); 538*0Sstevel@tonic-gate _scn = 0; 539*0Sstevel@tonic-gate while ((_scn = elf_nextscn(elf_file, _scn)) != 0) { 540*0Sstevel@tonic-gate if (gelf_getshdr(_scn, &_shdr) == 0) 541*0Sstevel@tonic-gate break; 542*0Sstevel@tonic-gate if ((_shdr.sh_type == SHT_SYMTAB_SHNDX) && 543*0Sstevel@tonic-gate /* LINTED */ 544*0Sstevel@tonic-gate (_shdr.sh_link == (GElf_Word)symscnndx)) { 545*0Sstevel@tonic-gate Elf_Data *_data; 546*0Sstevel@tonic-gate 547*0Sstevel@tonic-gate if ((_data = elf_getdata(_scn, 0)) == 0) 548*0Sstevel@tonic-gate continue; 549*0Sstevel@tonic-gate 550*0Sstevel@tonic-gate symshndx = (Elf32_Word *)_data->d_buf; 551*0Sstevel@tonic-gate nosymshndx = 0; 552*0Sstevel@tonic-gate break; 553*0Sstevel@tonic-gate } 554*0Sstevel@tonic-gate } 555*0Sstevel@tonic-gate nosymshndx = 1; 556*0Sstevel@tonic-gate } 557*0Sstevel@tonic-gate 558*0Sstevel@tonic-gate if ((symshndx) && (sym.st_shndx == SHN_XINDEX)) { 559*0Sstevel@tonic-gate shndx = symshndx[index]; 560*0Sstevel@tonic-gate specsec = 0; 561*0Sstevel@tonic-gate } else { 562*0Sstevel@tonic-gate shndx = sym.st_shndx; 563*0Sstevel@tonic-gate if ((sym.st_shndx == SHN_UNDEF) || 564*0Sstevel@tonic-gate (sym.st_shndx >= SHN_LORESERVE)) 565*0Sstevel@tonic-gate specsec = 1; 566*0Sstevel@tonic-gate else 567*0Sstevel@tonic-gate specsec = 0; 568*0Sstevel@tonic-gate } 569*0Sstevel@tonic-gate 570*0Sstevel@tonic-gate 571*0Sstevel@tonic-gate (void) printf("[%d]\t ", index++); 572*0Sstevel@tonic-gate 573*0Sstevel@tonic-gate if (v_flag && (type == STT_SPARC_REGISTER)) { 574*0Sstevel@tonic-gate /* 575*0Sstevel@tonic-gate * The strings "REG_G1" through "REG_G7" are intended 576*0Sstevel@tonic-gate * to be consistent with output from elfdump(1). 577*0Sstevel@tonic-gate */ 578*0Sstevel@tonic-gate switch (sym.st_value) { 579*0Sstevel@tonic-gate case STO_SPARC_REGISTER_G1: 580*0Sstevel@tonic-gate (void) printf("%-*s", 12 + adj, "REG_G1"); 581*0Sstevel@tonic-gate break; 582*0Sstevel@tonic-gate case STO_SPARC_REGISTER_G2: 583*0Sstevel@tonic-gate (void) printf("%-*s", 12 + adj, "REG_G2"); 584*0Sstevel@tonic-gate break; 585*0Sstevel@tonic-gate case STO_SPARC_REGISTER_G3: 586*0Sstevel@tonic-gate (void) printf("%-*s", 12 + adj, "REG_G3"); 587*0Sstevel@tonic-gate break; 588*0Sstevel@tonic-gate case STO_SPARC_REGISTER_G4: 589*0Sstevel@tonic-gate (void) printf("%-*s", 12 + adj, "REG_G4"); 590*0Sstevel@tonic-gate break; 591*0Sstevel@tonic-gate case STO_SPARC_REGISTER_G5: 592*0Sstevel@tonic-gate (void) printf("%-*s", 12 + adj, "REG_G5"); 593*0Sstevel@tonic-gate break; 594*0Sstevel@tonic-gate case STO_SPARC_REGISTER_G6: 595*0Sstevel@tonic-gate (void) printf("%-*s", 12 + adj, "REG_G6"); 596*0Sstevel@tonic-gate break; 597*0Sstevel@tonic-gate case STO_SPARC_REGISTER_G7: 598*0Sstevel@tonic-gate (void) printf("%-*s", 12 + adj, "REG_G7"); 599*0Sstevel@tonic-gate break; 600*0Sstevel@tonic-gate default: 601*0Sstevel@tonic-gate (void) printf("0x%-*llx", 10 + adj, 602*0Sstevel@tonic-gate EC_ADDR(sym.st_value)); 603*0Sstevel@tonic-gate } 604*0Sstevel@tonic-gate } else 605*0Sstevel@tonic-gate (void) printf("0x%-*llx", 10 + adj, 606*0Sstevel@tonic-gate EC_ADDR(sym.st_value)); 607*0Sstevel@tonic-gate 608*0Sstevel@tonic-gate (void) printf("%-*lld", 9 + adj, EC_XWORD(sym.st_size)); 609*0Sstevel@tonic-gate 610*0Sstevel@tonic-gate if (!v_flag) { 611*0Sstevel@tonic-gate (void) printf("%d\t\t%d\t%d\t%#x\t", 612*0Sstevel@tonic-gate type, bind, (int)sym.st_other, (int)shndx); 613*0Sstevel@tonic-gate } else { 614*0Sstevel@tonic-gate switch (type) { 615*0Sstevel@tonic-gate case STT_NOTYPE: 616*0Sstevel@tonic-gate (void) printf("%s\t", "NOTY"); 617*0Sstevel@tonic-gate break; 618*0Sstevel@tonic-gate case STT_OBJECT: 619*0Sstevel@tonic-gate (void) printf("%s\t", "OBJT"); 620*0Sstevel@tonic-gate break; 621*0Sstevel@tonic-gate case STT_FUNC: 622*0Sstevel@tonic-gate (void) printf("%s\t", "FUNC"); 623*0Sstevel@tonic-gate break; 624*0Sstevel@tonic-gate case STT_SECTION: 625*0Sstevel@tonic-gate (void) printf("%s\t", "SECT"); 626*0Sstevel@tonic-gate break; 627*0Sstevel@tonic-gate case STT_FILE: 628*0Sstevel@tonic-gate (void) printf("%s\t", "FILE"); 629*0Sstevel@tonic-gate break; 630*0Sstevel@tonic-gate case STT_SPARC_REGISTER: 631*0Sstevel@tonic-gate (void) printf("%s\t", "REGI"); 632*0Sstevel@tonic-gate break; 633*0Sstevel@tonic-gate case STT_COMMON: 634*0Sstevel@tonic-gate (void) printf("%s\t", "COMM"); 635*0Sstevel@tonic-gate break; 636*0Sstevel@tonic-gate case STT_TLS: 637*0Sstevel@tonic-gate (void) printf("%s\t", "TLS "); 638*0Sstevel@tonic-gate break; 639*0Sstevel@tonic-gate default: 640*0Sstevel@tonic-gate (void) printf("%d\t", type); 641*0Sstevel@tonic-gate } 642*0Sstevel@tonic-gate switch (bind) { 643*0Sstevel@tonic-gate case STB_LOCAL: 644*0Sstevel@tonic-gate (void) printf("LOCL"); 645*0Sstevel@tonic-gate break; 646*0Sstevel@tonic-gate case STB_GLOBAL: 647*0Sstevel@tonic-gate (void) printf("GLOB"); 648*0Sstevel@tonic-gate break; 649*0Sstevel@tonic-gate case STB_WEAK: 650*0Sstevel@tonic-gate (void) printf("WEAK"); 651*0Sstevel@tonic-gate break; 652*0Sstevel@tonic-gate default: 653*0Sstevel@tonic-gate (void) printf("%d", bind); 654*0Sstevel@tonic-gate } 655*0Sstevel@tonic-gate (void) printf("\t %d\t", EC_WORD(sym.st_other)); 656*0Sstevel@tonic-gate 657*0Sstevel@tonic-gate if (specsec) { 658*0Sstevel@tonic-gate switch (shndx) { 659*0Sstevel@tonic-gate case SHN_UNDEF: 660*0Sstevel@tonic-gate (void) printf("UNDEF"); 661*0Sstevel@tonic-gate break; 662*0Sstevel@tonic-gate case SHN_ABS: 663*0Sstevel@tonic-gate (void) printf("ABS"); 664*0Sstevel@tonic-gate break; 665*0Sstevel@tonic-gate case SHN_COMMON: 666*0Sstevel@tonic-gate (void) printf("COMMON"); 667*0Sstevel@tonic-gate break; 668*0Sstevel@tonic-gate case SHN_XINDEX: 669*0Sstevel@tonic-gate (void) printf("XINDEX"); 670*0Sstevel@tonic-gate break; 671*0Sstevel@tonic-gate default: 672*0Sstevel@tonic-gate (void) printf("%d", EC_WORD(shndx)); 673*0Sstevel@tonic-gate } 674*0Sstevel@tonic-gate } else 675*0Sstevel@tonic-gate (void) printf("%d", EC_WORD(shndx)); 676*0Sstevel@tonic-gate (void) printf("\t"); 677*0Sstevel@tonic-gate } 678*0Sstevel@tonic-gate 679*0Sstevel@tonic-gate /* support machines where NULL-deref causes core dump */ 680*0Sstevel@tonic-gate if (sym.st_name == 0) 681*0Sstevel@tonic-gate sym_name = (char *)UNKNOWN; 682*0Sstevel@tonic-gate else 683*0Sstevel@tonic-gate if (C_flag) 684*0Sstevel@tonic-gate sym_name = demangled_name( 685*0Sstevel@tonic-gate (char *)elf_strptr(elf_file, 686*0Sstevel@tonic-gate p_symtab->p_shdr.sh_link, 687*0Sstevel@tonic-gate sym.st_name)); 688*0Sstevel@tonic-gate else 689*0Sstevel@tonic-gate sym_name = (char *)elf_strptr(elf_file, 690*0Sstevel@tonic-gate p_symtab->p_shdr.sh_link, 691*0Sstevel@tonic-gate sym.st_name); 692*0Sstevel@tonic-gate if (sym_name == NULL) 693*0Sstevel@tonic-gate sym_name = (char *)UNKNOWN; 694*0Sstevel@tonic-gate (void) printf("%s\n", sym_name); 695*0Sstevel@tonic-gate 696*0Sstevel@tonic-gate range--; 697*0Sstevel@tonic-gate } /* end while */ 698*0Sstevel@tonic-gate } 699*0Sstevel@tonic-gate 700*0Sstevel@tonic-gate /* 701*0Sstevel@tonic-gate * Print the section header table. Input is the SCNTAB structure, 702*0Sstevel@tonic-gate * the number of sections, an index which is the number of the 703*0Sstevel@tonic-gate * section in the file, and the filename. The values of the SCNTAB 704*0Sstevel@tonic-gate * structure, the number of sections, and the index are set in 705*0Sstevel@tonic-gate * dump_shdr depending on whether the -n or -d modifiers were set. 706*0Sstevel@tonic-gate */ 707*0Sstevel@tonic-gate static void 708*0Sstevel@tonic-gate print_shdr(Elf *elf_file, SCNTAB *s, int num_scns, int index) 709*0Sstevel@tonic-gate { 710*0Sstevel@tonic-gate SCNTAB *p; 711*0Sstevel@tonic-gate int num; 712*0Sstevel@tonic-gate int field; 713*0Sstevel@tonic-gate 714*0Sstevel@tonic-gate if (gelf_getclass(elf_file) == ELFCLASS64) 715*0Sstevel@tonic-gate field = 15; 716*0Sstevel@tonic-gate else 717*0Sstevel@tonic-gate field = 13; 718*0Sstevel@tonic-gate 719*0Sstevel@tonic-gate p = s; 720*0Sstevel@tonic-gate 721*0Sstevel@tonic-gate for (num = 0; num < num_scns; num++, p++) { 722*0Sstevel@tonic-gate (void) printf("[%d]\t", index++); 723*0Sstevel@tonic-gate if (!v_flag) { 724*0Sstevel@tonic-gate (void) printf("%u\t%llu\t", 725*0Sstevel@tonic-gate EC_WORD(p->p_shdr.sh_type), 726*0Sstevel@tonic-gate EC_XWORD(p->p_shdr.sh_flags)); 727*0Sstevel@tonic-gate } else { 728*0Sstevel@tonic-gate switch (p->p_shdr.sh_type) { 729*0Sstevel@tonic-gate case SHT_NULL: 730*0Sstevel@tonic-gate (void) printf("NULL"); 731*0Sstevel@tonic-gate break; 732*0Sstevel@tonic-gate case SHT_PROGBITS: 733*0Sstevel@tonic-gate (void) printf("PBIT"); 734*0Sstevel@tonic-gate break; 735*0Sstevel@tonic-gate case SHT_SYMTAB: 736*0Sstevel@tonic-gate (void) printf("SYMT"); 737*0Sstevel@tonic-gate break; 738*0Sstevel@tonic-gate case SHT_STRTAB: 739*0Sstevel@tonic-gate (void) printf("STRT"); 740*0Sstevel@tonic-gate break; 741*0Sstevel@tonic-gate case SHT_RELA: 742*0Sstevel@tonic-gate (void) printf("RELA"); 743*0Sstevel@tonic-gate break; 744*0Sstevel@tonic-gate case SHT_HASH: 745*0Sstevel@tonic-gate (void) printf("HASH"); 746*0Sstevel@tonic-gate break; 747*0Sstevel@tonic-gate case SHT_DYNAMIC: 748*0Sstevel@tonic-gate (void) printf("DYNM"); 749*0Sstevel@tonic-gate break; 750*0Sstevel@tonic-gate case SHT_NOTE: 751*0Sstevel@tonic-gate (void) printf("NOTE"); 752*0Sstevel@tonic-gate break; 753*0Sstevel@tonic-gate case SHT_NOBITS: 754*0Sstevel@tonic-gate (void) printf("NOBI"); 755*0Sstevel@tonic-gate break; 756*0Sstevel@tonic-gate case SHT_REL: 757*0Sstevel@tonic-gate (void) printf("REL "); 758*0Sstevel@tonic-gate break; 759*0Sstevel@tonic-gate case SHT_DYNSYM: 760*0Sstevel@tonic-gate (void) printf("DYNS"); 761*0Sstevel@tonic-gate break; 762*0Sstevel@tonic-gate case ((GElf_Word) SHT_LOUSER): 763*0Sstevel@tonic-gate (void) printf("LUSR"); 764*0Sstevel@tonic-gate break; 765*0Sstevel@tonic-gate case ((GElf_Word) SHT_HIUSER): 766*0Sstevel@tonic-gate (void) printf("HUSR"); 767*0Sstevel@tonic-gate break; 768*0Sstevel@tonic-gate case SHT_SHLIB: 769*0Sstevel@tonic-gate (void) printf("SHLB"); 770*0Sstevel@tonic-gate break; 771*0Sstevel@tonic-gate case SHT_SUNW_SIGNATURE: 772*0Sstevel@tonic-gate (void) printf("SIGN"); 773*0Sstevel@tonic-gate break; 774*0Sstevel@tonic-gate case SHT_SUNW_ANNOTATE: 775*0Sstevel@tonic-gate (void) printf("ANOT"); 776*0Sstevel@tonic-gate break; 777*0Sstevel@tonic-gate case SHT_SUNW_DEBUGSTR: 778*0Sstevel@tonic-gate (void) printf("DBGS"); 779*0Sstevel@tonic-gate break; 780*0Sstevel@tonic-gate case SHT_SUNW_DEBUG: 781*0Sstevel@tonic-gate (void) printf("DBG "); 782*0Sstevel@tonic-gate break; 783*0Sstevel@tonic-gate case SHT_SUNW_move: 784*0Sstevel@tonic-gate (void) printf("MOVE"); 785*0Sstevel@tonic-gate break; 786*0Sstevel@tonic-gate case SHT_SUNW_verdef: 787*0Sstevel@tonic-gate (void) printf("VERD"); 788*0Sstevel@tonic-gate break; 789*0Sstevel@tonic-gate case SHT_SUNW_verneed: 790*0Sstevel@tonic-gate (void) printf("VERN"); 791*0Sstevel@tonic-gate break; 792*0Sstevel@tonic-gate case SHT_SUNW_versym: 793*0Sstevel@tonic-gate (void) printf("VERS"); 794*0Sstevel@tonic-gate break; 795*0Sstevel@tonic-gate case SHT_SUNW_syminfo: 796*0Sstevel@tonic-gate (void) printf("SYMI"); 797*0Sstevel@tonic-gate break; 798*0Sstevel@tonic-gate case SHT_SUNW_COMDAT: 799*0Sstevel@tonic-gate (void) printf("COMD"); 800*0Sstevel@tonic-gate break; 801*0Sstevel@tonic-gate default: 802*0Sstevel@tonic-gate (void) printf("%u", EC_WORD(p->p_shdr.sh_type)); 803*0Sstevel@tonic-gate break; 804*0Sstevel@tonic-gate } 805*0Sstevel@tonic-gate (void) printf(" "); 806*0Sstevel@tonic-gate 807*0Sstevel@tonic-gate if (p->p_shdr.sh_flags & SHF_WRITE) 808*0Sstevel@tonic-gate (void) printf("W"); 809*0Sstevel@tonic-gate else 810*0Sstevel@tonic-gate (void) printf("-"); 811*0Sstevel@tonic-gate if (p->p_shdr.sh_flags & SHF_ALLOC) 812*0Sstevel@tonic-gate (void) printf("A"); 813*0Sstevel@tonic-gate else 814*0Sstevel@tonic-gate (void) printf("-"); 815*0Sstevel@tonic-gate if (p->p_shdr.sh_flags & SHF_EXECINSTR) 816*0Sstevel@tonic-gate (void) printf("I"); 817*0Sstevel@tonic-gate else 818*0Sstevel@tonic-gate (void) printf("-"); 819*0Sstevel@tonic-gate 820*0Sstevel@tonic-gate if (p->p_shdr.sh_flags & SHF_ORDERED) 821*0Sstevel@tonic-gate (void) printf("O"); 822*0Sstevel@tonic-gate if (p->p_shdr.sh_flags & SHF_EXCLUDE) 823*0Sstevel@tonic-gate (void) printf("E"); 824*0Sstevel@tonic-gate 825*0Sstevel@tonic-gate (void) printf("\t"); 826*0Sstevel@tonic-gate 827*0Sstevel@tonic-gate } 828*0Sstevel@tonic-gate (void) printf("%-#*llx%-#*llx%-#*llx%s%s\n", 829*0Sstevel@tonic-gate field, EC_ADDR(p->p_shdr.sh_addr), 830*0Sstevel@tonic-gate field, EC_OFF(p->p_shdr.sh_offset), 831*0Sstevel@tonic-gate field, EC_XWORD(p->p_shdr.sh_size), 832*0Sstevel@tonic-gate /* compatibility: tab for elf32 */ 833*0Sstevel@tonic-gate (field == 13) ? "\t" : " ", p->scn_name); 834*0Sstevel@tonic-gate 835*0Sstevel@tonic-gate (void) printf("\t%u\t%u\t%-#*llx%-#*llx\n\n", 836*0Sstevel@tonic-gate EC_WORD(p->p_shdr.sh_link), 837*0Sstevel@tonic-gate EC_WORD(p->p_shdr.sh_info), 838*0Sstevel@tonic-gate field, EC_XWORD(p->p_shdr.sh_addralign), 839*0Sstevel@tonic-gate field, EC_XWORD(p->p_shdr.sh_entsize)); 840*0Sstevel@tonic-gate } 841*0Sstevel@tonic-gate } 842*0Sstevel@tonic-gate 843*0Sstevel@tonic-gate /* 844*0Sstevel@tonic-gate * Check that a range of numbers is valid. Input is 845*0Sstevel@tonic-gate * a lower bound, an upper bound, a boundary condition, 846*0Sstevel@tonic-gate * and the filename. Negative numbers and numbers greater 847*0Sstevel@tonic-gate * than the bound are invalid. low must be smaller than hi. 848*0Sstevel@tonic-gate * The returned integer is the number of items in the 849*0Sstevel@tonic-gate * range if it is valid and -1 otherwise. 850*0Sstevel@tonic-gate */ 851*0Sstevel@tonic-gate static int 852*0Sstevel@tonic-gate check_range(int low, int hi, size_t bound, char *filename) 853*0Sstevel@tonic-gate { 854*0Sstevel@tonic-gate if (((size_t)low > bound) || (low <= 0)) { 855*0Sstevel@tonic-gate (void) fprintf(stderr, 856*0Sstevel@tonic-gate "%s: %s: number out of range, %d\n", 857*0Sstevel@tonic-gate prog_name, filename, low); 858*0Sstevel@tonic-gate return (-1); 859*0Sstevel@tonic-gate } 860*0Sstevel@tonic-gate if (((size_t)hi > bound) || (hi < 0)) { 861*0Sstevel@tonic-gate (void) fprintf(stderr, 862*0Sstevel@tonic-gate "%s: %s: number out of range, %d\n", 863*0Sstevel@tonic-gate prog_name, filename, hi); 864*0Sstevel@tonic-gate return (-1); 865*0Sstevel@tonic-gate } 866*0Sstevel@tonic-gate 867*0Sstevel@tonic-gate if (hi && (low > hi)) { 868*0Sstevel@tonic-gate (void) fprintf(stderr, 869*0Sstevel@tonic-gate "%s: %s: invalid range, %d,%d\n", 870*0Sstevel@tonic-gate prog_name, filename, low, hi); 871*0Sstevel@tonic-gate return (-1); 872*0Sstevel@tonic-gate } 873*0Sstevel@tonic-gate if (hi) 874*0Sstevel@tonic-gate return (hi - low + 1); 875*0Sstevel@tonic-gate else 876*0Sstevel@tonic-gate return (1); 877*0Sstevel@tonic-gate } 878*0Sstevel@tonic-gate 879*0Sstevel@tonic-gate /* 880*0Sstevel@tonic-gate * Print relocation information. Since this information is 881*0Sstevel@tonic-gate * machine dependent, new sections must be added for each machine 882*0Sstevel@tonic-gate * that is supported. Input is an ELF file descriptor, the ELF header, 883*0Sstevel@tonic-gate * the SCNTAB structure, the number of sections, and a filename. 884*0Sstevel@tonic-gate * Set up necessary information to print relocation information 885*0Sstevel@tonic-gate * and call the appropriate print function depending on the 886*0Sstevel@tonic-gate * type of relocation information. If the symbol table is 887*0Sstevel@tonic-gate * absent, no relocation data is processed. Input is an 888*0Sstevel@tonic-gate * ELF file descriptor, the ELF header, the SCNTAB structure, 889*0Sstevel@tonic-gate * and the filename. Set range of d_flag and name if n_flag. 890*0Sstevel@tonic-gate */ 891*0Sstevel@tonic-gate static void 892*0Sstevel@tonic-gate dump_reloc_table(Elf *elf_file, GElf_Ehdr *p_ehdr, 893*0Sstevel@tonic-gate SCNTAB *p_scns, int num_scns, char *filename) 894*0Sstevel@tonic-gate { 895*0Sstevel@tonic-gate Elf_Data *rel_data; 896*0Sstevel@tonic-gate Elf_Data *sym_data; 897*0Sstevel@tonic-gate size_t sym_size; 898*0Sstevel@tonic-gate size_t reloc_size; 899*0Sstevel@tonic-gate SCNTAB *reloc_symtab; 900*0Sstevel@tonic-gate SCNTAB *head_scns; 901*0Sstevel@tonic-gate int r_title = 0; 902*0Sstevel@tonic-gate int adj = 0; 903*0Sstevel@tonic-gate size_t shnum; 904*0Sstevel@tonic-gate 905*0Sstevel@tonic-gate if (gelf_getclass(elf_file) == ELFCLASS64) 906*0Sstevel@tonic-gate adj = 4; 907*0Sstevel@tonic-gate 908*0Sstevel@tonic-gate if ((!p_flag) && (!r_title)) { 909*0Sstevel@tonic-gate (void) printf("\n **** RELOCATION INFORMATION ****\n"); 910*0Sstevel@tonic-gate r_title = 1; 911*0Sstevel@tonic-gate } 912*0Sstevel@tonic-gate 913*0Sstevel@tonic-gate while (num_scns-- > 0) { 914*0Sstevel@tonic-gate if ((p_scns->p_shdr.sh_type != SHT_RELA) && 915*0Sstevel@tonic-gate (p_scns->p_shdr.sh_type != SHT_REL)) { 916*0Sstevel@tonic-gate p_scns++; 917*0Sstevel@tonic-gate continue; 918*0Sstevel@tonic-gate } 919*0Sstevel@tonic-gate 920*0Sstevel@tonic-gate head_scns = p_head_scns; 921*0Sstevel@tonic-gate 922*0Sstevel@tonic-gate if (elf_getshnum(elf_file, &shnum) == 0) { 923*0Sstevel@tonic-gate (void) fprintf(stderr, 924*0Sstevel@tonic-gate "%s: %s: elf_getshnum failed: %s\n", 925*0Sstevel@tonic-gate prog_name, filename, elf_errmsg(-1)); 926*0Sstevel@tonic-gate return; 927*0Sstevel@tonic-gate } 928*0Sstevel@tonic-gate 929*0Sstevel@tonic-gate if ((p_scns->p_shdr.sh_link == 0) || 930*0Sstevel@tonic-gate /* LINTED */ 931*0Sstevel@tonic-gate (p_scns->p_shdr.sh_link >= (GElf_Word)shnum)) { 932*0Sstevel@tonic-gate (void) fprintf(stderr, "%s: %s: invalid sh_link field: " 933*0Sstevel@tonic-gate "section #: %d sh_link: %d\n", 934*0Sstevel@tonic-gate /* LINTED */ 935*0Sstevel@tonic-gate prog_name, filename, (int)elf_ndxscn(p_scns->p_sd), 936*0Sstevel@tonic-gate (int)p_scns->p_shdr.sh_link); 937*0Sstevel@tonic-gate return; 938*0Sstevel@tonic-gate } 939*0Sstevel@tonic-gate head_scns += (p_scns->p_shdr.sh_link -1); 940*0Sstevel@tonic-gate 941*0Sstevel@tonic-gate if (head_scns->p_shdr.sh_type == SHT_SYMTAB) { 942*0Sstevel@tonic-gate reloc_symtab = p_symtab; 943*0Sstevel@tonic-gate } else if (head_scns->p_shdr.sh_type == SHT_DYNSYM) { 944*0Sstevel@tonic-gate reloc_symtab = p_dynsym; 945*0Sstevel@tonic-gate } else { 946*0Sstevel@tonic-gate (void) fprintf(stderr, 947*0Sstevel@tonic-gate "%s: %s: could not get symbol table\n", prog_name, filename); 948*0Sstevel@tonic-gate return; 949*0Sstevel@tonic-gate } 950*0Sstevel@tonic-gate 951*0Sstevel@tonic-gate sym_data = NULL; 952*0Sstevel@tonic-gate sym_size = 0; 953*0Sstevel@tonic-gate reloc_size = 0; 954*0Sstevel@tonic-gate 955*0Sstevel@tonic-gate if ((sym_data = elf_getdata(reloc_symtab->p_sd, NULL)) == NULL) { 956*0Sstevel@tonic-gate (void) fprintf(stderr, 957*0Sstevel@tonic-gate "%s: %s: no symbol table data\n", prog_name, filename); 958*0Sstevel@tonic-gate return; 959*0Sstevel@tonic-gate } 960*0Sstevel@tonic-gate sym_size = sym_data->d_size; 961*0Sstevel@tonic-gate 962*0Sstevel@tonic-gate if (p_scns == NULL) { 963*0Sstevel@tonic-gate (void) fprintf(stderr, 964*0Sstevel@tonic-gate "%s: %s: no section table data\n", prog_name, filename); 965*0Sstevel@tonic-gate return; 966*0Sstevel@tonic-gate } 967*0Sstevel@tonic-gate 968*0Sstevel@tonic-gate if (p_scns->p_shdr.sh_type == SHT_RELA) { 969*0Sstevel@tonic-gate if (!n_flag && r_flag) 970*0Sstevel@tonic-gate (void) printf("\n%s:\n", p_scns->scn_name); 971*0Sstevel@tonic-gate if (!p_flag && (!n_flag && r_flag)) 972*0Sstevel@tonic-gate (void) printf("%-*s%-*s%-*s%s\n\n", 973*0Sstevel@tonic-gate 12 + adj, "Offset", 22, "Symndx", 974*0Sstevel@tonic-gate 18, "Type", "Addend"); 975*0Sstevel@tonic-gate if ((rel_data = elf_getdata(p_scns->p_sd, NULL)) == NULL) { 976*0Sstevel@tonic-gate (void) fprintf(stderr, 977*0Sstevel@tonic-gate "%s: %s: no relocation information\n", prog_name, filename); 978*0Sstevel@tonic-gate return; 979*0Sstevel@tonic-gate } 980*0Sstevel@tonic-gate reloc_size = rel_data->d_size; 981*0Sstevel@tonic-gate 982*0Sstevel@tonic-gate if (n_flag) { 983*0Sstevel@tonic-gate rn_flag = 1; 984*0Sstevel@tonic-gate print_rela(elf_file, p_scns, rel_data, sym_data, p_ehdr, 985*0Sstevel@tonic-gate reloc_size, sym_size, filename, reloc_symtab); 986*0Sstevel@tonic-gate } 987*0Sstevel@tonic-gate if (d_flag) { 988*0Sstevel@tonic-gate rn_flag = 0; 989*0Sstevel@tonic-gate print_rela(elf_file, p_scns, rel_data, sym_data, p_ehdr, 990*0Sstevel@tonic-gate reloc_size, sym_size, filename, reloc_symtab); 991*0Sstevel@tonic-gate } 992*0Sstevel@tonic-gate if (!n_flag && !d_flag) 993*0Sstevel@tonic-gate print_rela(elf_file, p_scns, rel_data, sym_data, p_ehdr, 994*0Sstevel@tonic-gate reloc_size, sym_size, filename, reloc_symtab); 995*0Sstevel@tonic-gate } else { 996*0Sstevel@tonic-gate if (p_scns->p_shdr.sh_type == SHT_REL) { 997*0Sstevel@tonic-gate if (!n_flag && r_flag) 998*0Sstevel@tonic-gate (void) printf("\n%s:\n", p_scns->scn_name); 999*0Sstevel@tonic-gate if (!p_flag && (!n_flag && r_flag)) { 1000*0Sstevel@tonic-gate (void) printf("%-*s%-*s%s\n\n", 1001*0Sstevel@tonic-gate 12 + adj, "Offset", 20, "Symndx", "Type"); 1002*0Sstevel@tonic-gate } 1003*0Sstevel@tonic-gate if ((rel_data = elf_getdata(p_scns->p_sd, NULL)) 1004*0Sstevel@tonic-gate == NULL) { 1005*0Sstevel@tonic-gate (void) fprintf(stderr, 1006*0Sstevel@tonic-gate "%s: %s: no relocation information\n", prog_name, filename); 1007*0Sstevel@tonic-gate return; 1008*0Sstevel@tonic-gate } 1009*0Sstevel@tonic-gate reloc_size = rel_data->d_size; 1010*0Sstevel@tonic-gate if (n_flag) { 1011*0Sstevel@tonic-gate rn_flag = 1; 1012*0Sstevel@tonic-gate print_rel(elf_file, p_scns, rel_data, sym_data, 1013*0Sstevel@tonic-gate p_ehdr, reloc_size, sym_size, 1014*0Sstevel@tonic-gate filename, reloc_symtab); 1015*0Sstevel@tonic-gate } 1016*0Sstevel@tonic-gate if (d_flag) { 1017*0Sstevel@tonic-gate rn_flag = 0; 1018*0Sstevel@tonic-gate print_rel(elf_file, p_scns, rel_data, sym_data, 1019*0Sstevel@tonic-gate p_ehdr, reloc_size, sym_size, 1020*0Sstevel@tonic-gate filename, reloc_symtab); 1021*0Sstevel@tonic-gate } 1022*0Sstevel@tonic-gate if (!n_flag && !d_flag) 1023*0Sstevel@tonic-gate print_rel(elf_file, p_scns, rel_data, sym_data, 1024*0Sstevel@tonic-gate p_ehdr, reloc_size, sym_size, 1025*0Sstevel@tonic-gate filename, reloc_symtab); 1026*0Sstevel@tonic-gate } 1027*0Sstevel@tonic-gate } 1028*0Sstevel@tonic-gate p_scns++; 1029*0Sstevel@tonic-gate } 1030*0Sstevel@tonic-gate } 1031*0Sstevel@tonic-gate 1032*0Sstevel@tonic-gate /* 1033*0Sstevel@tonic-gate * Print out the string tables. Input is an opened ELF file, 1034*0Sstevel@tonic-gate * the SCNTAB structure, the number of sections, and the filename. 1035*0Sstevel@tonic-gate * Since there can be more than one string table, all sections are 1036*0Sstevel@tonic-gate * examined and any with the correct type are printed out. 1037*0Sstevel@tonic-gate */ 1038*0Sstevel@tonic-gate static void 1039*0Sstevel@tonic-gate dump_string_table(SCNTAB *s, int num_scns) 1040*0Sstevel@tonic-gate { 1041*0Sstevel@tonic-gate size_t section_size; 1042*0Sstevel@tonic-gate unsigned char *strtab; 1043*0Sstevel@tonic-gate int beg_of_string; 1044*0Sstevel@tonic-gate int counter = 0; 1045*0Sstevel@tonic-gate int str_off; 1046*0Sstevel@tonic-gate int i; 1047*0Sstevel@tonic-gate 1048*0Sstevel@tonic-gate if (!p_flag) { 1049*0Sstevel@tonic-gate (void) printf("\n **** STRING TABLE INFORMATION ****\n"); 1050*0Sstevel@tonic-gate } 1051*0Sstevel@tonic-gate 1052*0Sstevel@tonic-gate for (i = 0; i < num_scns; i++, s++) { 1053*0Sstevel@tonic-gate if (s->p_shdr.sh_type != SHT_STRTAB) 1054*0Sstevel@tonic-gate continue; 1055*0Sstevel@tonic-gate 1056*0Sstevel@tonic-gate str_off = 0; 1057*0Sstevel@tonic-gate 1058*0Sstevel@tonic-gate if (!p_flag) { 1059*0Sstevel@tonic-gate (void) printf("\n%s:\n", s->scn_name); 1060*0Sstevel@tonic-gate (void) printf(" <offset> \tName\n"); 1061*0Sstevel@tonic-gate } 1062*0Sstevel@tonic-gate section_size = 0; 1063*0Sstevel@tonic-gate if ((strtab = (unsigned char *) 1064*0Sstevel@tonic-gate get_scndata(s->p_sd, §ion_size)) == NULL) { 1065*0Sstevel@tonic-gate continue; 1066*0Sstevel@tonic-gate } 1067*0Sstevel@tonic-gate 1068*0Sstevel@tonic-gate if (section_size != 0) { 1069*0Sstevel@tonic-gate (void) printf(" <%d> \t", str_off); 1070*0Sstevel@tonic-gate beg_of_string = 0; 1071*0Sstevel@tonic-gate while (section_size--) { 1072*0Sstevel@tonic-gate unsigned char c = *strtab++; 1073*0Sstevel@tonic-gate 1074*0Sstevel@tonic-gate if (beg_of_string) { 1075*0Sstevel@tonic-gate (void) printf(" <%d> \t", str_off); 1076*0Sstevel@tonic-gate counter++; 1077*0Sstevel@tonic-gate beg_of_string = 0; 1078*0Sstevel@tonic-gate } 1079*0Sstevel@tonic-gate str_off++; 1080*0Sstevel@tonic-gate switch (c) { 1081*0Sstevel@tonic-gate case '\0': 1082*0Sstevel@tonic-gate (void) printf("\n"); 1083*0Sstevel@tonic-gate beg_of_string = 1; 1084*0Sstevel@tonic-gate break; 1085*0Sstevel@tonic-gate default: 1086*0Sstevel@tonic-gate (void) putchar(c); 1087*0Sstevel@tonic-gate } 1088*0Sstevel@tonic-gate } 1089*0Sstevel@tonic-gate } 1090*0Sstevel@tonic-gate } 1091*0Sstevel@tonic-gate (void) printf("\n"); 1092*0Sstevel@tonic-gate } 1093*0Sstevel@tonic-gate 1094*0Sstevel@tonic-gate /* 1095*0Sstevel@tonic-gate * Print the symbol table. This function does not print the contents 1096*0Sstevel@tonic-gate * of the symbol table but sets up the parameters and then calls 1097*0Sstevel@tonic-gate * print_symtab to print the symbols. Calling another function to print 1098*0Sstevel@tonic-gate * the symbols allows both -T and -n to work correctly 1099*0Sstevel@tonic-gate * simultaneously. Input is an opened ELF file, a pointer to the 1100*0Sstevel@tonic-gate * symbol table SCNTAB structure, and the filename. 1101*0Sstevel@tonic-gate * Set the range of symbols to print if T_flag, and set 1102*0Sstevel@tonic-gate * name of symbol to print if n_flag. 1103*0Sstevel@tonic-gate */ 1104*0Sstevel@tonic-gate static void 1105*0Sstevel@tonic-gate dump_symbol_table(Elf *elf_file, SCNTAB *p_symtab, char *filename) 1106*0Sstevel@tonic-gate { 1107*0Sstevel@tonic-gate Elf_Data *sym_data; 1108*0Sstevel@tonic-gate GElf_Sym T_range, n_range; /* for use with -T and -n */ 1109*0Sstevel@tonic-gate size_t count = 0; 1110*0Sstevel@tonic-gate size_t sym_size; 1111*0Sstevel@tonic-gate int index = 1; 1112*0Sstevel@tonic-gate int found_it = 0; 1113*0Sstevel@tonic-gate int i; 1114*0Sstevel@tonic-gate int adj = 0; /* field adjustment for elf64 */ 1115*0Sstevel@tonic-gate 1116*0Sstevel@tonic-gate if (gelf_getclass(elf_file) == ELFCLASS64) 1117*0Sstevel@tonic-gate adj = 4; 1118*0Sstevel@tonic-gate 1119*0Sstevel@tonic-gate if (p_symtab == NULL) { 1120*0Sstevel@tonic-gate (void) fprintf(stderr, 1121*0Sstevel@tonic-gate "%s: %s: could not get symbol table\n", prog_name, filename); 1122*0Sstevel@tonic-gate return; 1123*0Sstevel@tonic-gate } 1124*0Sstevel@tonic-gate 1125*0Sstevel@tonic-gate /* get symbol table data */ 1126*0Sstevel@tonic-gate sym_data = NULL; 1127*0Sstevel@tonic-gate sym_size = 0; 1128*0Sstevel@tonic-gate if ((sym_data = 1129*0Sstevel@tonic-gate elf_getdata(p_symtab->p_sd, NULL)) == NULL) { 1130*0Sstevel@tonic-gate (void) printf("\n%s:\n", p_symtab->scn_name); 1131*0Sstevel@tonic-gate (void) printf("No symbol table data\n"); 1132*0Sstevel@tonic-gate return; 1133*0Sstevel@tonic-gate } 1134*0Sstevel@tonic-gate sym_size = sym_data->d_size; 1135*0Sstevel@tonic-gate 1136*0Sstevel@tonic-gate count = sym_size / p_symtab->p_shdr.sh_entsize; 1137*0Sstevel@tonic-gate 1138*0Sstevel@tonic-gate if (n_flag && t_flag && !T_flag) { 1139*0Sstevel@tonic-gate /* LINTED */ 1140*0Sstevel@tonic-gate for (i = 1; i < count; i++) { 1141*0Sstevel@tonic-gate (void) gelf_getsym(sym_data, i, &n_range); 1142*0Sstevel@tonic-gate if (strcmp(name, (char *) 1143*0Sstevel@tonic-gate elf_strptr(elf_file, 1144*0Sstevel@tonic-gate p_symtab->p_shdr.sh_link, 1145*0Sstevel@tonic-gate n_range.st_name)) != 0) { 1146*0Sstevel@tonic-gate continue; 1147*0Sstevel@tonic-gate } else { 1148*0Sstevel@tonic-gate found_it = 1; 1149*0Sstevel@tonic-gate if (!p_flag) { 1150*0Sstevel@tonic-gate (void) printf( 1151*0Sstevel@tonic-gate "\n ***** SYMBOL TABLE INFORMATION *****\n"); 1152*0Sstevel@tonic-gate (void) printf( 1153*0Sstevel@tonic-gate "[Index] %-*s%-*sType\tBind\tOther\tShndx\tName", 1154*0Sstevel@tonic-gate 12 + adj, "Value", 9 + adj, "Size"); 1155*0Sstevel@tonic-gate } 1156*0Sstevel@tonic-gate (void) printf("\n%s:\n", p_symtab->scn_name); 1157*0Sstevel@tonic-gate print_symtab(elf_file, p_symtab, sym_data, 1158*0Sstevel@tonic-gate 1, i); 1159*0Sstevel@tonic-gate } 1160*0Sstevel@tonic-gate } /* end for */ 1161*0Sstevel@tonic-gate if (!found_it) { 1162*0Sstevel@tonic-gate (void) fprintf(stderr, "%s: %s: %s not found\n", 1163*0Sstevel@tonic-gate prog_name, filename, name); 1164*0Sstevel@tonic-gate } 1165*0Sstevel@tonic-gate } else if (T_flag) { 1166*0Sstevel@tonic-gate T_num = check_range(T_low, T_hi, count, filename); 1167*0Sstevel@tonic-gate if (T_num < 0) 1168*0Sstevel@tonic-gate return; 1169*0Sstevel@tonic-gate 1170*0Sstevel@tonic-gate (void) gelf_getsym(sym_data, T_low-1, &T_range); 1171*0Sstevel@tonic-gate index = T_low; 1172*0Sstevel@tonic-gate 1173*0Sstevel@tonic-gate if (!p_flag) { 1174*0Sstevel@tonic-gate (void) printf( 1175*0Sstevel@tonic-gate "\n ***** SYMBOL TABLE INFORMATION *****\n"); 1176*0Sstevel@tonic-gate (void) printf( 1177*0Sstevel@tonic-gate "[Index] %-*s%-*sType\tBind\tOther\tShndx\tName", 1178*0Sstevel@tonic-gate 12 + adj, "Value", 9 + adj, "Size"); 1179*0Sstevel@tonic-gate } 1180*0Sstevel@tonic-gate (void) printf("\n%s:\n", p_symtab->scn_name); 1181*0Sstevel@tonic-gate print_symtab(elf_file, p_symtab, sym_data, T_num, index); 1182*0Sstevel@tonic-gate } else { 1183*0Sstevel@tonic-gate if (!p_flag) { 1184*0Sstevel@tonic-gate (void) printf( 1185*0Sstevel@tonic-gate "\n ***** SYMBOL TABLE INFORMATION *****\n"); 1186*0Sstevel@tonic-gate (void) printf( 1187*0Sstevel@tonic-gate "[Index] %-*s%-*sType\tBind\tOther\tShndx\tName", 1188*0Sstevel@tonic-gate 12 + adj, "Value", 9 + adj, "Size"); 1189*0Sstevel@tonic-gate } 1190*0Sstevel@tonic-gate (void) printf("\n%s:\n", p_symtab->scn_name); 1191*0Sstevel@tonic-gate print_symtab(elf_file, p_symtab, sym_data, count-1, 1); 1192*0Sstevel@tonic-gate } 1193*0Sstevel@tonic-gate } 1194*0Sstevel@tonic-gate 1195*0Sstevel@tonic-gate /* 1196*0Sstevel@tonic-gate * Print dynamic linking information. Input is an ELF 1197*0Sstevel@tonic-gate * file descriptor, the SCNTAB structure, the number of 1198*0Sstevel@tonic-gate * sections, and the filename. 1199*0Sstevel@tonic-gate */ 1200*0Sstevel@tonic-gate static void 1201*0Sstevel@tonic-gate dump_dynamic(Elf *elf_file, SCNTAB *p_scns, int num_scns, char *filename) 1202*0Sstevel@tonic-gate { 1203*0Sstevel@tonic-gate Elf_Data *dyn_data; 1204*0Sstevel@tonic-gate GElf_Dyn p_dyn; 1205*0Sstevel@tonic-gate GElf_Phdr p_phdr; 1206*0Sstevel@tonic-gate GElf_Ehdr p_ehdr; 1207*0Sstevel@tonic-gate char *dt_name; 1208*0Sstevel@tonic-gate int index = 1; 1209*0Sstevel@tonic-gate int lib_scns = num_scns; 1210*0Sstevel@tonic-gate SCNTAB *l_scns = p_scns; 1211*0Sstevel@tonic-gate int header_num = 0; 1212*0Sstevel@tonic-gate #define Fmttag "%-15.15s " 1213*0Sstevel@tonic-gate #define Fmtptr "%#llx" 1214*0Sstevel@tonic-gate 1215*0Sstevel@tonic-gate if (!p_flag) 1216*0Sstevel@tonic-gate (void) printf("\n **** DYNAMIC SECTION INFORMATION ****\n"); 1217*0Sstevel@tonic-gate 1218*0Sstevel@tonic-gate for (; num_scns > 0; num_scns--, p_scns++) { 1219*0Sstevel@tonic-gate GElf_Word link; 1220*0Sstevel@tonic-gate int ii; 1221*0Sstevel@tonic-gate 1222*0Sstevel@tonic-gate 1223*0Sstevel@tonic-gate if (p_scns->p_shdr.sh_type != SHT_DYNAMIC) 1224*0Sstevel@tonic-gate continue; 1225*0Sstevel@tonic-gate 1226*0Sstevel@tonic-gate if (!p_flag) { 1227*0Sstevel@tonic-gate (void) printf("%s:\n", p_scns->scn_name); 1228*0Sstevel@tonic-gate (void) printf("[INDEX]\tTag Value\n"); 1229*0Sstevel@tonic-gate } 1230*0Sstevel@tonic-gate 1231*0Sstevel@tonic-gate if ((dyn_data = elf_getdata(p_scns->p_sd, NULL)) == 0) { 1232*0Sstevel@tonic-gate (void) fprintf(stderr, "%s: %s: no data in " 1233*0Sstevel@tonic-gate "%s section\n", prog_name, filename, 1234*0Sstevel@tonic-gate p_scns->scn_name); 1235*0Sstevel@tonic-gate return; 1236*0Sstevel@tonic-gate } 1237*0Sstevel@tonic-gate 1238*0Sstevel@tonic-gate link = p_scns->p_shdr.sh_link; 1239*0Sstevel@tonic-gate ii = 0; 1240*0Sstevel@tonic-gate 1241*0Sstevel@tonic-gate (void) gelf_getdyn(dyn_data, ii++, &p_dyn); 1242*0Sstevel@tonic-gate while (p_dyn.d_tag != DT_NULL) { 1243*0Sstevel@tonic-gate char value[256]; 1244*0Sstevel@tonic-gate 1245*0Sstevel@tonic-gate (void) printf("[%d]\t", index++); 1246*0Sstevel@tonic-gate 1247*0Sstevel@tonic-gate switch (p_dyn.d_tag) { 1248*0Sstevel@tonic-gate /* 1249*0Sstevel@tonic-gate * Start of generic flags. 1250*0Sstevel@tonic-gate */ 1251*0Sstevel@tonic-gate case (DT_NEEDED): 1252*0Sstevel@tonic-gate (void) printf(Fmttag, (const char *)"NEEDED"); 1253*0Sstevel@tonic-gate if (v_flag) 1254*0Sstevel@tonic-gate dt_name = (char *)elf_strptr(elf_file, 1255*0Sstevel@tonic-gate link, p_dyn.d_un.d_ptr); 1256*0Sstevel@tonic-gate if (dt_name == NULL) 1257*0Sstevel@tonic-gate dt_name = (char *)UNKNOWN; 1258*0Sstevel@tonic-gate if (v_flag && strlen(dt_name)) 1259*0Sstevel@tonic-gate (void) printf("%s", dt_name); 1260*0Sstevel@tonic-gate else 1261*0Sstevel@tonic-gate (void) printf(Fmtptr, 1262*0Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_ptr)); 1263*0Sstevel@tonic-gate break; 1264*0Sstevel@tonic-gate case (DT_PLTRELSZ): 1265*0Sstevel@tonic-gate (void) printf(Fmttag, (const char *)"PLTSZ"); 1266*0Sstevel@tonic-gate (void) printf(Fmtptr, 1267*0Sstevel@tonic-gate EC_XWORD(p_dyn.d_un.d_val)); 1268*0Sstevel@tonic-gate break; 1269*0Sstevel@tonic-gate case (DT_PLTGOT): 1270*0Sstevel@tonic-gate (void) printf(Fmttag, (const char *)"PLTGOT"); 1271*0Sstevel@tonic-gate (void) printf(Fmtptr, 1272*0Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_ptr)); 1273*0Sstevel@tonic-gate break; 1274*0Sstevel@tonic-gate case (DT_HASH): 1275*0Sstevel@tonic-gate (void) printf(Fmttag, (const char *)"HASH"); 1276*0Sstevel@tonic-gate (void) printf(Fmtptr, 1277*0Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_ptr)); 1278*0Sstevel@tonic-gate break; 1279*0Sstevel@tonic-gate case (DT_STRTAB): 1280*0Sstevel@tonic-gate (void) printf(Fmttag, (const char *)"STRTAB"); 1281*0Sstevel@tonic-gate (void) printf(Fmtptr, 1282*0Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_ptr)); 1283*0Sstevel@tonic-gate break; 1284*0Sstevel@tonic-gate case (DT_SYMTAB): 1285*0Sstevel@tonic-gate (void) printf(Fmttag, (const char *)"SYMTAB"); 1286*0Sstevel@tonic-gate (void) printf(Fmtptr, 1287*0Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_ptr)); 1288*0Sstevel@tonic-gate break; 1289*0Sstevel@tonic-gate case (DT_RELA): 1290*0Sstevel@tonic-gate (void) printf(Fmttag, (const char *)"RELA"); 1291*0Sstevel@tonic-gate (void) printf(Fmtptr, 1292*0Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_ptr)); 1293*0Sstevel@tonic-gate break; 1294*0Sstevel@tonic-gate case (DT_RELASZ): 1295*0Sstevel@tonic-gate (void) printf(Fmttag, (const char *)"RELASZ"); 1296*0Sstevel@tonic-gate (void) printf(Fmtptr, 1297*0Sstevel@tonic-gate EC_XWORD(p_dyn.d_un.d_val)); 1298*0Sstevel@tonic-gate break; 1299*0Sstevel@tonic-gate case (DT_RELAENT): 1300*0Sstevel@tonic-gate (void) printf(Fmttag, (const char *)"RELAENT"); 1301*0Sstevel@tonic-gate (void) printf(Fmtptr, 1302*0Sstevel@tonic-gate EC_XWORD(p_dyn.d_un.d_val)); 1303*0Sstevel@tonic-gate break; 1304*0Sstevel@tonic-gate case (DT_STRSZ): 1305*0Sstevel@tonic-gate (void) printf(Fmttag, (const char *)"STRSZ"); 1306*0Sstevel@tonic-gate (void) printf(Fmtptr, 1307*0Sstevel@tonic-gate EC_XWORD(p_dyn.d_un.d_val)); 1308*0Sstevel@tonic-gate break; 1309*0Sstevel@tonic-gate case (DT_SYMENT): 1310*0Sstevel@tonic-gate (void) printf(Fmttag, (const char *)"SYMENT"); 1311*0Sstevel@tonic-gate (void) printf(Fmtptr, 1312*0Sstevel@tonic-gate EC_XWORD(p_dyn.d_un.d_val)); 1313*0Sstevel@tonic-gate break; 1314*0Sstevel@tonic-gate case (DT_INIT): 1315*0Sstevel@tonic-gate (void) printf(Fmttag, (const char *)"INIT"); 1316*0Sstevel@tonic-gate (void) printf(Fmtptr, 1317*0Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_ptr)); 1318*0Sstevel@tonic-gate break; 1319*0Sstevel@tonic-gate case (DT_FINI): 1320*0Sstevel@tonic-gate (void) printf(Fmttag, (const char *)"FINI"); 1321*0Sstevel@tonic-gate (void) printf(Fmtptr, 1322*0Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_ptr)); 1323*0Sstevel@tonic-gate break; 1324*0Sstevel@tonic-gate case (DT_SONAME): 1325*0Sstevel@tonic-gate (void) printf(Fmttag, (const char *)"SONAME"); 1326*0Sstevel@tonic-gate if (v_flag) 1327*0Sstevel@tonic-gate dt_name = (char *)elf_strptr(elf_file, 1328*0Sstevel@tonic-gate link, p_dyn.d_un.d_ptr); 1329*0Sstevel@tonic-gate if (dt_name == NULL) 1330*0Sstevel@tonic-gate dt_name = (char *)UNKNOWN; 1331*0Sstevel@tonic-gate if (v_flag && strlen(dt_name)) 1332*0Sstevel@tonic-gate (void) printf("%s", dt_name); 1333*0Sstevel@tonic-gate else 1334*0Sstevel@tonic-gate (void) printf(Fmtptr, 1335*0Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_ptr)); 1336*0Sstevel@tonic-gate break; 1337*0Sstevel@tonic-gate case (DT_RPATH): 1338*0Sstevel@tonic-gate (void) printf(Fmttag, (const char *)"RPATH"); 1339*0Sstevel@tonic-gate if (v_flag) 1340*0Sstevel@tonic-gate dt_name = (char *)elf_strptr(elf_file, 1341*0Sstevel@tonic-gate link, p_dyn.d_un.d_ptr); 1342*0Sstevel@tonic-gate if (dt_name == NULL) 1343*0Sstevel@tonic-gate dt_name = (char *)UNKNOWN; 1344*0Sstevel@tonic-gate if (v_flag && strlen(dt_name)) 1345*0Sstevel@tonic-gate (void) printf("%s", dt_name); 1346*0Sstevel@tonic-gate else 1347*0Sstevel@tonic-gate (void) printf(Fmtptr, 1348*0Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_ptr)); 1349*0Sstevel@tonic-gate break; 1350*0Sstevel@tonic-gate case (DT_SYMBOLIC): 1351*0Sstevel@tonic-gate (void) printf(Fmttag, (const char *)"SYMB"); 1352*0Sstevel@tonic-gate (void) printf("%s", (const char *)"(ignored)"); 1353*0Sstevel@tonic-gate break; 1354*0Sstevel@tonic-gate case (DT_REL): 1355*0Sstevel@tonic-gate (void) printf(Fmttag, (const char *)"REL"); 1356*0Sstevel@tonic-gate (void) printf(Fmtptr, 1357*0Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_ptr)); 1358*0Sstevel@tonic-gate break; 1359*0Sstevel@tonic-gate case (DT_RELSZ): 1360*0Sstevel@tonic-gate (void) printf(Fmttag, (const char *)"RELSZ"); 1361*0Sstevel@tonic-gate (void) printf(Fmtptr, 1362*0Sstevel@tonic-gate EC_XWORD(p_dyn.d_un.d_val)); 1363*0Sstevel@tonic-gate break; 1364*0Sstevel@tonic-gate case (DT_RELENT): 1365*0Sstevel@tonic-gate (void) printf(Fmttag, (const char *)"RELENT"); 1366*0Sstevel@tonic-gate (void) printf(Fmtptr, 1367*0Sstevel@tonic-gate EC_XWORD(p_dyn.d_un.d_val)); 1368*0Sstevel@tonic-gate break; 1369*0Sstevel@tonic-gate case (DT_PLTREL): 1370*0Sstevel@tonic-gate (void) printf(Fmttag, (const char *)"PLTREL"); 1371*0Sstevel@tonic-gate (void) printf(Fmtptr, 1372*0Sstevel@tonic-gate EC_XWORD(p_dyn.d_un.d_val)); 1373*0Sstevel@tonic-gate break; 1374*0Sstevel@tonic-gate case (DT_DEBUG): 1375*0Sstevel@tonic-gate (void) printf(Fmttag, (const char *)"DEBUG"); 1376*0Sstevel@tonic-gate (void) printf(Fmtptr, 1377*0Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_ptr)); 1378*0Sstevel@tonic-gate break; 1379*0Sstevel@tonic-gate case (DT_TEXTREL): 1380*0Sstevel@tonic-gate (void) printf(Fmttag, (const char *)"TEXTREL"); 1381*0Sstevel@tonic-gate (void) printf(Fmtptr, 1382*0Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_val)); 1383*0Sstevel@tonic-gate break; 1384*0Sstevel@tonic-gate case (DT_JMPREL): 1385*0Sstevel@tonic-gate (void) printf(Fmttag, (const char *)"JMPREL"); 1386*0Sstevel@tonic-gate (void) printf(Fmtptr, 1387*0Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_ptr)); 1388*0Sstevel@tonic-gate break; 1389*0Sstevel@tonic-gate case (DT_BIND_NOW): 1390*0Sstevel@tonic-gate (void) printf(Fmttag, (const char *)"BIND_NOW"); 1391*0Sstevel@tonic-gate (void) printf(Fmtptr, 1392*0Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_val)); 1393*0Sstevel@tonic-gate break; 1394*0Sstevel@tonic-gate case (DT_INIT_ARRAY): 1395*0Sstevel@tonic-gate (void) printf(Fmttag, 1396*0Sstevel@tonic-gate (const char *)"INIT_ARRAY"); 1397*0Sstevel@tonic-gate (void) printf(Fmtptr, 1398*0Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_ptr)); 1399*0Sstevel@tonic-gate break; 1400*0Sstevel@tonic-gate case (DT_FINI_ARRAY): 1401*0Sstevel@tonic-gate (void) printf(Fmttag, 1402*0Sstevel@tonic-gate (const char *)"FINI_ARRAY"); 1403*0Sstevel@tonic-gate (void) printf(Fmtptr, 1404*0Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_ptr)); 1405*0Sstevel@tonic-gate break; 1406*0Sstevel@tonic-gate case (DT_INIT_ARRAYSZ): 1407*0Sstevel@tonic-gate (void) printf(Fmttag, 1408*0Sstevel@tonic-gate (const char *)"INIT_ARRAYSZ"); 1409*0Sstevel@tonic-gate (void) printf(Fmtptr, 1410*0Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_ptr)); 1411*0Sstevel@tonic-gate break; 1412*0Sstevel@tonic-gate case (DT_FINI_ARRAYSZ): 1413*0Sstevel@tonic-gate (void) printf(Fmttag, 1414*0Sstevel@tonic-gate (const char *)"FINI_ARRAYSZ"); 1415*0Sstevel@tonic-gate (void) printf(Fmtptr, 1416*0Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_ptr)); 1417*0Sstevel@tonic-gate break; 1418*0Sstevel@tonic-gate case (DT_RUNPATH): 1419*0Sstevel@tonic-gate (void) printf(Fmttag, (const char *)"RUNPATH"); 1420*0Sstevel@tonic-gate if (v_flag) 1421*0Sstevel@tonic-gate dt_name = (char *)elf_strptr(elf_file, 1422*0Sstevel@tonic-gate link, p_dyn.d_un.d_ptr); 1423*0Sstevel@tonic-gate if (dt_name == NULL) 1424*0Sstevel@tonic-gate dt_name = (char *)UNKNOWN; 1425*0Sstevel@tonic-gate if (v_flag && strlen(dt_name)) 1426*0Sstevel@tonic-gate (void) printf("%s", dt_name); 1427*0Sstevel@tonic-gate else 1428*0Sstevel@tonic-gate (void) printf(Fmtptr, 1429*0Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_ptr)); 1430*0Sstevel@tonic-gate break; 1431*0Sstevel@tonic-gate case (DT_FLAGS): 1432*0Sstevel@tonic-gate (void) printf(Fmttag, 1433*0Sstevel@tonic-gate (const char *)"FLAGS"); 1434*0Sstevel@tonic-gate value[0] = '\0'; 1435*0Sstevel@tonic-gate if (v_flag) { 1436*0Sstevel@tonic-gate if (p_dyn.d_un.d_val & DF_ORIGIN) 1437*0Sstevel@tonic-gate (void) strcat(value, 1438*0Sstevel@tonic-gate (const char *)"ORIGIN "); 1439*0Sstevel@tonic-gate if (p_dyn.d_un.d_val & DF_SYMBOLIC) 1440*0Sstevel@tonic-gate (void) strcat(value, 1441*0Sstevel@tonic-gate (const char *)"SYMBOLIC "); 1442*0Sstevel@tonic-gate if (p_dyn.d_un.d_val & DF_TEXTREL) 1443*0Sstevel@tonic-gate (void) strcat(value, 1444*0Sstevel@tonic-gate (const char *)"TEXTREL "); 1445*0Sstevel@tonic-gate if (p_dyn.d_un.d_val & DF_BIND_NOW) 1446*0Sstevel@tonic-gate (void) strcat(value, 1447*0Sstevel@tonic-gate (const char *)"BIND_NOW "); 1448*0Sstevel@tonic-gate if (p_dyn.d_un.d_val & DF_STATIC_TLS) 1449*0Sstevel@tonic-gate (void) strcat(value, 1450*0Sstevel@tonic-gate (const char *)"STATIC_TLS "); 1451*0Sstevel@tonic-gate } 1452*0Sstevel@tonic-gate if (v_flag && strlen(value)) 1453*0Sstevel@tonic-gate (void) printf("%s", value); 1454*0Sstevel@tonic-gate else 1455*0Sstevel@tonic-gate (void) printf(Fmtptr, 1456*0Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_ptr)); 1457*0Sstevel@tonic-gate break; 1458*0Sstevel@tonic-gate case (DT_PREINIT_ARRAY): 1459*0Sstevel@tonic-gate (void) printf(Fmttag, 1460*0Sstevel@tonic-gate (const char *)"PRINIT_ARRAY"); 1461*0Sstevel@tonic-gate (void) printf(Fmtptr, 1462*0Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_ptr)); 1463*0Sstevel@tonic-gate break; 1464*0Sstevel@tonic-gate case (DT_PREINIT_ARRAYSZ): 1465*0Sstevel@tonic-gate (void) printf(Fmttag, 1466*0Sstevel@tonic-gate (const char *)"PRINIT_ARRAYSZ"); 1467*0Sstevel@tonic-gate (void) printf(Fmtptr, 1468*0Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_ptr)); 1469*0Sstevel@tonic-gate break; 1470*0Sstevel@tonic-gate /* 1471*0Sstevel@tonic-gate * DT_LOOS - DT_HIOS range. 1472*0Sstevel@tonic-gate */ 1473*0Sstevel@tonic-gate case (DT_SUNW_AUXILIARY): 1474*0Sstevel@tonic-gate (void) printf(Fmttag, 1475*0Sstevel@tonic-gate (const char *)"SUNW_AUXILIARY"); 1476*0Sstevel@tonic-gate if (v_flag) 1477*0Sstevel@tonic-gate dt_name = (char *)elf_strptr(elf_file, 1478*0Sstevel@tonic-gate link, p_dyn.d_un.d_ptr); 1479*0Sstevel@tonic-gate if (dt_name == NULL) 1480*0Sstevel@tonic-gate dt_name = (char *)UNKNOWN; 1481*0Sstevel@tonic-gate if (v_flag && strlen(dt_name)) 1482*0Sstevel@tonic-gate (void) printf("%s", dt_name); 1483*0Sstevel@tonic-gate else 1484*0Sstevel@tonic-gate (void) printf(Fmtptr, 1485*0Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_ptr)); 1486*0Sstevel@tonic-gate break; 1487*0Sstevel@tonic-gate case (DT_SUNW_RTLDINF): 1488*0Sstevel@tonic-gate (void) printf(Fmttag, 1489*0Sstevel@tonic-gate (const char *)"SUNW_RTLDINF"); 1490*0Sstevel@tonic-gate (void) printf(Fmtptr, 1491*0Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_ptr)); 1492*0Sstevel@tonic-gate break; 1493*0Sstevel@tonic-gate case (DT_SUNW_FILTER): 1494*0Sstevel@tonic-gate (void) printf(Fmttag, 1495*0Sstevel@tonic-gate (const char *)"SUNW_FILTER"); 1496*0Sstevel@tonic-gate if (v_flag) 1497*0Sstevel@tonic-gate dt_name = (char *)elf_strptr(elf_file, 1498*0Sstevel@tonic-gate link, p_dyn.d_un.d_ptr); 1499*0Sstevel@tonic-gate if (dt_name == NULL) 1500*0Sstevel@tonic-gate dt_name = (char *)UNKNOWN; 1501*0Sstevel@tonic-gate if (v_flag && strlen(dt_name)) 1502*0Sstevel@tonic-gate (void) printf("%s", dt_name); 1503*0Sstevel@tonic-gate else 1504*0Sstevel@tonic-gate (void) printf(Fmtptr, 1505*0Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_ptr)); 1506*0Sstevel@tonic-gate break; 1507*0Sstevel@tonic-gate case (DT_SUNW_CAP): 1508*0Sstevel@tonic-gate (void) printf(Fmttag, 1509*0Sstevel@tonic-gate (const char *)"SUNW_CAP"); 1510*0Sstevel@tonic-gate (void) printf(Fmtptr, 1511*0Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_ptr)); 1512*0Sstevel@tonic-gate break; 1513*0Sstevel@tonic-gate 1514*0Sstevel@tonic-gate /* 1515*0Sstevel@tonic-gate * SUNW: DT_VALRNGLO - DT_VALRNGHI range. 1516*0Sstevel@tonic-gate */ 1517*0Sstevel@tonic-gate case (DT_CHECKSUM): 1518*0Sstevel@tonic-gate (void) printf(Fmttag, 1519*0Sstevel@tonic-gate (const char *)"CHECKSUM"); 1520*0Sstevel@tonic-gate (void) printf(Fmtptr, 1521*0Sstevel@tonic-gate EC_XWORD(p_dyn.d_un.d_val)); 1522*0Sstevel@tonic-gate break; 1523*0Sstevel@tonic-gate case (DT_PLTPADSZ): 1524*0Sstevel@tonic-gate (void) printf(Fmttag, 1525*0Sstevel@tonic-gate (const char *)"PLTPADSZ"); 1526*0Sstevel@tonic-gate (void) printf(Fmtptr, 1527*0Sstevel@tonic-gate EC_XWORD(p_dyn.d_un.d_val)); 1528*0Sstevel@tonic-gate break; 1529*0Sstevel@tonic-gate case (DT_MOVEENT): 1530*0Sstevel@tonic-gate (void) printf(Fmttag, 1531*0Sstevel@tonic-gate (const char *)"MOVEENT"); 1532*0Sstevel@tonic-gate (void) printf(Fmtptr, 1533*0Sstevel@tonic-gate EC_XWORD(p_dyn.d_un.d_val)); 1534*0Sstevel@tonic-gate break; 1535*0Sstevel@tonic-gate case (DT_MOVESZ): 1536*0Sstevel@tonic-gate (void) printf(Fmttag, 1537*0Sstevel@tonic-gate (const char *)"MOVESZ"); 1538*0Sstevel@tonic-gate (void) printf(Fmtptr, 1539*0Sstevel@tonic-gate EC_XWORD(p_dyn.d_un.d_val)); 1540*0Sstevel@tonic-gate break; 1541*0Sstevel@tonic-gate case (DT_FEATURE_1): 1542*0Sstevel@tonic-gate (void) printf(Fmttag, 1543*0Sstevel@tonic-gate (const char *)"FEATURE_1"); 1544*0Sstevel@tonic-gate value[0] = '\0'; 1545*0Sstevel@tonic-gate if (v_flag) { 1546*0Sstevel@tonic-gate if (p_dyn.d_un.d_val & DTF_1_PARINIT) 1547*0Sstevel@tonic-gate (void) strcat(value, 1548*0Sstevel@tonic-gate (const char *)"PARINIT "); 1549*0Sstevel@tonic-gate if (p_dyn.d_un.d_val & DTF_1_CONFEXP) 1550*0Sstevel@tonic-gate (void) strcat(value, 1551*0Sstevel@tonic-gate (const char *)"CONFEXP "); 1552*0Sstevel@tonic-gate } 1553*0Sstevel@tonic-gate if (v_flag && strlen(value)) 1554*0Sstevel@tonic-gate (void) printf("%s", value); 1555*0Sstevel@tonic-gate else 1556*0Sstevel@tonic-gate (void) printf(Fmtptr, 1557*0Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_ptr)); 1558*0Sstevel@tonic-gate break; 1559*0Sstevel@tonic-gate case (DT_POSFLAG_1): 1560*0Sstevel@tonic-gate (void) printf(Fmttag, 1561*0Sstevel@tonic-gate (const char *)"POSFLAG_1"); 1562*0Sstevel@tonic-gate value[0] = '\0'; 1563*0Sstevel@tonic-gate if (v_flag) { 1564*0Sstevel@tonic-gate if (p_dyn.d_un.d_val & DF_P1_LAZYLOAD) 1565*0Sstevel@tonic-gate (void) strcat(value, 1566*0Sstevel@tonic-gate (const char *)"LAZYLOAD "); 1567*0Sstevel@tonic-gate if (p_dyn.d_un.d_val & DF_P1_GROUPPERM) 1568*0Sstevel@tonic-gate (void) strcat(value, 1569*0Sstevel@tonic-gate (const char *)"GROUPPERM "); 1570*0Sstevel@tonic-gate } 1571*0Sstevel@tonic-gate if (v_flag && strlen(value)) 1572*0Sstevel@tonic-gate (void) printf("%s", value); 1573*0Sstevel@tonic-gate else 1574*0Sstevel@tonic-gate (void) printf(Fmtptr, 1575*0Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_ptr)); 1576*0Sstevel@tonic-gate break; 1577*0Sstevel@tonic-gate case (DT_SYMINSZ): 1578*0Sstevel@tonic-gate (void) printf(Fmttag, 1579*0Sstevel@tonic-gate (const char *)"SYMINSZ"); 1580*0Sstevel@tonic-gate (void) printf(Fmtptr, 1581*0Sstevel@tonic-gate EC_XWORD(p_dyn.d_un.d_val)); 1582*0Sstevel@tonic-gate break; 1583*0Sstevel@tonic-gate case (DT_SYMINENT): 1584*0Sstevel@tonic-gate (void) printf(Fmttag, 1585*0Sstevel@tonic-gate (const char *)"SYMINENT"); 1586*0Sstevel@tonic-gate (void) printf(Fmtptr, 1587*0Sstevel@tonic-gate EC_XWORD(p_dyn.d_un.d_val)); 1588*0Sstevel@tonic-gate break; 1589*0Sstevel@tonic-gate 1590*0Sstevel@tonic-gate /* 1591*0Sstevel@tonic-gate * SUNW: DT_ADDRRNGLO - DT_ADDRRNGHI range. 1592*0Sstevel@tonic-gate */ 1593*0Sstevel@tonic-gate case (DT_CONFIG): 1594*0Sstevel@tonic-gate (void) printf(Fmttag, (const char *)"CONFIG"); 1595*0Sstevel@tonic-gate if (v_flag) 1596*0Sstevel@tonic-gate dt_name = (char *)elf_strptr(elf_file, 1597*0Sstevel@tonic-gate link, p_dyn.d_un.d_ptr); 1598*0Sstevel@tonic-gate if (dt_name == NULL) 1599*0Sstevel@tonic-gate dt_name = (char *)UNKNOWN; 1600*0Sstevel@tonic-gate if (v_flag && strlen(dt_name)) 1601*0Sstevel@tonic-gate (void) printf("%s", dt_name); 1602*0Sstevel@tonic-gate else 1603*0Sstevel@tonic-gate (void) printf(Fmtptr, 1604*0Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_ptr)); 1605*0Sstevel@tonic-gate break; 1606*0Sstevel@tonic-gate case (DT_DEPAUDIT): 1607*0Sstevel@tonic-gate (void) printf(Fmttag, 1608*0Sstevel@tonic-gate (const char *)"DEPAUDIT"); 1609*0Sstevel@tonic-gate if (v_flag) 1610*0Sstevel@tonic-gate dt_name = (char *)elf_strptr(elf_file, 1611*0Sstevel@tonic-gate link, p_dyn.d_un.d_ptr); 1612*0Sstevel@tonic-gate if (dt_name == NULL) 1613*0Sstevel@tonic-gate dt_name = (char *)UNKNOWN; 1614*0Sstevel@tonic-gate if (v_flag && strlen(dt_name)) 1615*0Sstevel@tonic-gate (void) printf("%s", dt_name); 1616*0Sstevel@tonic-gate else 1617*0Sstevel@tonic-gate (void) printf(Fmtptr, 1618*0Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_ptr)); 1619*0Sstevel@tonic-gate break; 1620*0Sstevel@tonic-gate case (DT_AUDIT): 1621*0Sstevel@tonic-gate (void) printf(Fmttag, 1622*0Sstevel@tonic-gate (const char *)"AUDIT"); 1623*0Sstevel@tonic-gate if (v_flag) 1624*0Sstevel@tonic-gate dt_name = (char *)elf_strptr(elf_file, 1625*0Sstevel@tonic-gate link, p_dyn.d_un.d_ptr); 1626*0Sstevel@tonic-gate if (dt_name == NULL) 1627*0Sstevel@tonic-gate dt_name = (char *)UNKNOWN; 1628*0Sstevel@tonic-gate if (v_flag && strlen(dt_name)) 1629*0Sstevel@tonic-gate (void) printf("%s", dt_name); 1630*0Sstevel@tonic-gate else 1631*0Sstevel@tonic-gate (void) printf(Fmtptr, 1632*0Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_ptr)); 1633*0Sstevel@tonic-gate break; 1634*0Sstevel@tonic-gate case (DT_PLTPAD): 1635*0Sstevel@tonic-gate (void) printf(Fmttag, 1636*0Sstevel@tonic-gate (const char *)"PLTPAD"); 1637*0Sstevel@tonic-gate (void) printf(Fmtptr, 1638*0Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_ptr)); 1639*0Sstevel@tonic-gate break; 1640*0Sstevel@tonic-gate case (DT_MOVETAB): 1641*0Sstevel@tonic-gate (void) printf(Fmttag, 1642*0Sstevel@tonic-gate (const char *)"MOVETAB"); 1643*0Sstevel@tonic-gate (void) printf(Fmtptr, 1644*0Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_ptr)); 1645*0Sstevel@tonic-gate break; 1646*0Sstevel@tonic-gate case (DT_SYMINFO): 1647*0Sstevel@tonic-gate (void) printf(Fmttag, 1648*0Sstevel@tonic-gate (const char *)"SYMINFO"); 1649*0Sstevel@tonic-gate (void) printf(Fmtptr, 1650*0Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_ptr)); 1651*0Sstevel@tonic-gate break; 1652*0Sstevel@tonic-gate 1653*0Sstevel@tonic-gate /* 1654*0Sstevel@tonic-gate * SUNW: generic range. 1655*0Sstevel@tonic-gate */ 1656*0Sstevel@tonic-gate case (DT_RELACOUNT): 1657*0Sstevel@tonic-gate (void) printf(Fmttag, 1658*0Sstevel@tonic-gate (const char *)"RELACOUNT"); 1659*0Sstevel@tonic-gate (void) printf(Fmtptr, 1660*0Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_ptr)); 1661*0Sstevel@tonic-gate break; 1662*0Sstevel@tonic-gate case (DT_RELCOUNT): 1663*0Sstevel@tonic-gate (void) printf(Fmttag, 1664*0Sstevel@tonic-gate (const char *)"RELCOUNT"); 1665*0Sstevel@tonic-gate (void) printf(Fmtptr, 1666*0Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_ptr)); 1667*0Sstevel@tonic-gate break; 1668*0Sstevel@tonic-gate case (DT_FLAGS_1): 1669*0Sstevel@tonic-gate (void) printf(Fmttag, 1670*0Sstevel@tonic-gate (const char *)"FLAGS_1"); 1671*0Sstevel@tonic-gate value[0] = '\0'; 1672*0Sstevel@tonic-gate if (v_flag) { 1673*0Sstevel@tonic-gate if (p_dyn.d_un.d_val & DF_1_NOW) 1674*0Sstevel@tonic-gate (void) strcat(value, 1675*0Sstevel@tonic-gate (const char *)"NOW "); 1676*0Sstevel@tonic-gate if (p_dyn.d_un.d_val & DF_1_GLOBAL) 1677*0Sstevel@tonic-gate (void) strcat(value, 1678*0Sstevel@tonic-gate (const char *)"GLOBAL "); 1679*0Sstevel@tonic-gate if (p_dyn.d_un.d_val & DF_1_GROUP) 1680*0Sstevel@tonic-gate (void) strcat(value, 1681*0Sstevel@tonic-gate (const char *)"GROUP "); 1682*0Sstevel@tonic-gate if (p_dyn.d_un.d_val & DF_1_NODELETE) 1683*0Sstevel@tonic-gate (void) strcat(value, 1684*0Sstevel@tonic-gate (const char *)"NODELETE "); 1685*0Sstevel@tonic-gate if (p_dyn.d_un.d_val & DF_1_LOADFLTR) 1686*0Sstevel@tonic-gate (void) strcat(value, 1687*0Sstevel@tonic-gate (const char *)"LOADFLTR "); 1688*0Sstevel@tonic-gate if (p_dyn.d_un.d_val & DF_1_INITFIRST) 1689*0Sstevel@tonic-gate (void) strcat(value, 1690*0Sstevel@tonic-gate (const char *)"INITFIRST "); 1691*0Sstevel@tonic-gate if (p_dyn.d_un.d_val & DF_1_NOOPEN) 1692*0Sstevel@tonic-gate (void) strcat(value, 1693*0Sstevel@tonic-gate (const char *)"NOOPEN "); 1694*0Sstevel@tonic-gate if (p_dyn.d_un.d_val & DF_1_ORIGIN) 1695*0Sstevel@tonic-gate (void) strcat(value, 1696*0Sstevel@tonic-gate (const char *)"ORIGIN "); 1697*0Sstevel@tonic-gate if (p_dyn.d_un.d_val & DF_1_DIRECT) 1698*0Sstevel@tonic-gate (void) strcat(value, 1699*0Sstevel@tonic-gate (const char *)"DIRECT "); 1700*0Sstevel@tonic-gate if (p_dyn.d_un.d_val & DF_1_TRANS) 1701*0Sstevel@tonic-gate (void) strcat(value, 1702*0Sstevel@tonic-gate (const char *)"TRANS "); 1703*0Sstevel@tonic-gate if (p_dyn.d_un.d_val & DF_1_INTERPOSE) 1704*0Sstevel@tonic-gate (void) strcat(value, 1705*0Sstevel@tonic-gate (const char *)"INTERPOSE "); 1706*0Sstevel@tonic-gate if (p_dyn.d_un.d_val & DF_1_NODEFLIB) 1707*0Sstevel@tonic-gate (void) strcat(value, 1708*0Sstevel@tonic-gate (const char *)"NODEFLIB "); 1709*0Sstevel@tonic-gate if (p_dyn.d_un.d_val & DF_1_NODUMP) 1710*0Sstevel@tonic-gate (void) strcat(value, 1711*0Sstevel@tonic-gate (const char *)"NODUMP "); 1712*0Sstevel@tonic-gate if (p_dyn.d_un.d_val & DF_1_CONFALT) 1713*0Sstevel@tonic-gate (void) strcat(value, 1714*0Sstevel@tonic-gate (const char *)"CONFALT "); 1715*0Sstevel@tonic-gate if (p_dyn.d_un.d_val & DF_1_ENDFILTEE) 1716*0Sstevel@tonic-gate (void) strcat(value, 1717*0Sstevel@tonic-gate (const char *)"ENDFILTEE "); 1718*0Sstevel@tonic-gate if (p_dyn.d_un.d_val & DF_1_DISPRELDNE) 1719*0Sstevel@tonic-gate (void) strcat(value, 1720*0Sstevel@tonic-gate (const char *)"DISPRELDONE "); 1721*0Sstevel@tonic-gate if (p_dyn.d_un.d_val & DF_1_DISPRELPND) 1722*0Sstevel@tonic-gate (void) strcat(value, 1723*0Sstevel@tonic-gate (const char *)"DISPRELPND "); 1724*0Sstevel@tonic-gate if (p_dyn.d_un.d_val & DF_1_IGNMULDEF) 1725*0Sstevel@tonic-gate (void) strcat(value, 1726*0Sstevel@tonic-gate (const char *)"IGNMULDEF "); 1727*0Sstevel@tonic-gate if (p_dyn.d_un.d_val & DF_1_NOKSYMS) 1728*0Sstevel@tonic-gate (void) strcat(value, 1729*0Sstevel@tonic-gate (const char *)"NOKSYMS "); 1730*0Sstevel@tonic-gate } 1731*0Sstevel@tonic-gate if (v_flag && strlen(value)) 1732*0Sstevel@tonic-gate (void) printf("%s", value); 1733*0Sstevel@tonic-gate else 1734*0Sstevel@tonic-gate (void) printf(Fmtptr, 1735*0Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_ptr)); 1736*0Sstevel@tonic-gate break; 1737*0Sstevel@tonic-gate case (DT_VERSYM): 1738*0Sstevel@tonic-gate (void) printf(Fmttag, (const char *)"VERSYM"); 1739*0Sstevel@tonic-gate (void) printf(Fmtptr, 1740*0Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_ptr)); 1741*0Sstevel@tonic-gate break; 1742*0Sstevel@tonic-gate case (DT_VERDEF): 1743*0Sstevel@tonic-gate (void) printf(Fmttag, (const char *)"VERDEF"); 1744*0Sstevel@tonic-gate (void) printf(Fmtptr, 1745*0Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_ptr)); 1746*0Sstevel@tonic-gate break; 1747*0Sstevel@tonic-gate case (DT_VERDEFNUM): 1748*0Sstevel@tonic-gate (void) printf(Fmttag, 1749*0Sstevel@tonic-gate (const char *)"VERDEFNUM"); 1750*0Sstevel@tonic-gate (void) printf(Fmtptr, 1751*0Sstevel@tonic-gate EC_XWORD(p_dyn.d_un.d_val)); 1752*0Sstevel@tonic-gate break; 1753*0Sstevel@tonic-gate case (DT_VERNEED): 1754*0Sstevel@tonic-gate (void) printf(Fmttag, (const char *)"VERNEED"); 1755*0Sstevel@tonic-gate (void) printf(Fmtptr, 1756*0Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_ptr)); 1757*0Sstevel@tonic-gate break; 1758*0Sstevel@tonic-gate case (DT_VERNEEDNUM): 1759*0Sstevel@tonic-gate (void) printf(Fmttag, 1760*0Sstevel@tonic-gate (const char *)"VERNEEDNUM"); 1761*0Sstevel@tonic-gate (void) printf(Fmtptr, 1762*0Sstevel@tonic-gate EC_XWORD(p_dyn.d_un.d_val)); 1763*0Sstevel@tonic-gate break; 1764*0Sstevel@tonic-gate case (DT_AUXILIARY): 1765*0Sstevel@tonic-gate (void) printf(Fmttag, 1766*0Sstevel@tonic-gate (const char *)"AUXILIARY"); 1767*0Sstevel@tonic-gate if (v_flag) 1768*0Sstevel@tonic-gate dt_name = (char *)elf_strptr(elf_file, 1769*0Sstevel@tonic-gate link, p_dyn.d_un.d_ptr); 1770*0Sstevel@tonic-gate if (dt_name == NULL) 1771*0Sstevel@tonic-gate dt_name = (char *)UNKNOWN; 1772*0Sstevel@tonic-gate if (v_flag && strlen(dt_name)) 1773*0Sstevel@tonic-gate (void) printf("%s", dt_name); 1774*0Sstevel@tonic-gate else 1775*0Sstevel@tonic-gate (void) printf(Fmtptr, 1776*0Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_ptr)); 1777*0Sstevel@tonic-gate break; 1778*0Sstevel@tonic-gate case (DT_USED): 1779*0Sstevel@tonic-gate (void) printf(Fmttag, (const char *)"USED"); 1780*0Sstevel@tonic-gate if (v_flag) 1781*0Sstevel@tonic-gate dt_name = (char *)elf_strptr(elf_file, 1782*0Sstevel@tonic-gate link, p_dyn.d_un.d_ptr); 1783*0Sstevel@tonic-gate if (dt_name == NULL) 1784*0Sstevel@tonic-gate dt_name = (char *)UNKNOWN; 1785*0Sstevel@tonic-gate if (v_flag && strlen(dt_name)) 1786*0Sstevel@tonic-gate (void) printf("%s", dt_name); 1787*0Sstevel@tonic-gate else 1788*0Sstevel@tonic-gate (void) printf(Fmtptr, 1789*0Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_ptr)); 1790*0Sstevel@tonic-gate break; 1791*0Sstevel@tonic-gate case (DT_FILTER): 1792*0Sstevel@tonic-gate (void) printf(Fmttag, (const char *)"FILTER"); 1793*0Sstevel@tonic-gate if (v_flag) 1794*0Sstevel@tonic-gate dt_name = (char *)elf_strptr(elf_file, 1795*0Sstevel@tonic-gate link, p_dyn.d_un.d_ptr); 1796*0Sstevel@tonic-gate if (dt_name == NULL) 1797*0Sstevel@tonic-gate dt_name = (char *)UNKNOWN; 1798*0Sstevel@tonic-gate if (v_flag && strlen(dt_name)) 1799*0Sstevel@tonic-gate (void) printf("%s", dt_name); 1800*0Sstevel@tonic-gate else 1801*0Sstevel@tonic-gate (void) printf(Fmtptr, 1802*0Sstevel@tonic-gate EC_ADDR(p_dyn.d_un.d_ptr)); 1803*0Sstevel@tonic-gate break; 1804*0Sstevel@tonic-gate 1805*0Sstevel@tonic-gate /* 1806*0Sstevel@tonic-gate * SUNW: machine specific range. 1807*0Sstevel@tonic-gate */ 1808*0Sstevel@tonic-gate case (DT_SPARC_REGISTER): 1809*0Sstevel@tonic-gate (void) printf(Fmttag, 1810*0Sstevel@tonic-gate (const char *)"REGISTER"); 1811*0Sstevel@tonic-gate (void) printf(Fmtptr, 1812*0Sstevel@tonic-gate EC_XWORD(p_dyn.d_un.d_val)); 1813*0Sstevel@tonic-gate break; 1814*0Sstevel@tonic-gate case (DT_DEPRECATED_SPARC_REGISTER): 1815*0Sstevel@tonic-gate (void) printf(Fmttag, 1816*0Sstevel@tonic-gate (const char *)"REGISTER"); 1817*0Sstevel@tonic-gate (void) printf("%#llx (deprecated value)", 1818*0Sstevel@tonic-gate EC_XWORD(p_dyn.d_un.d_val)); 1819*0Sstevel@tonic-gate break; 1820*0Sstevel@tonic-gate default: 1821*0Sstevel@tonic-gate (void) printf("%lld", EC_XWORD(p_dyn.d_tag)); 1822*0Sstevel@tonic-gate break; 1823*0Sstevel@tonic-gate } 1824*0Sstevel@tonic-gate (void) printf("\n"); 1825*0Sstevel@tonic-gate (void) gelf_getdyn(dyn_data, ii++, &p_dyn); 1826*0Sstevel@tonic-gate } 1827*0Sstevel@tonic-gate } 1828*0Sstevel@tonic-gate 1829*0Sstevel@tonic-gate /* 1830*0Sstevel@tonic-gate * Check for existence of static shared library information. 1831*0Sstevel@tonic-gate */ 1832*0Sstevel@tonic-gate (void) gelf_getehdr(elf_file, &p_ehdr); 1833*0Sstevel@tonic-gate while (header_num < p_ehdr.e_phnum) { 1834*0Sstevel@tonic-gate (void) gelf_getphdr(elf_file, header_num, &p_phdr); 1835*0Sstevel@tonic-gate if (p_phdr.p_type == PT_SHLIB) { 1836*0Sstevel@tonic-gate while (--lib_scns > 0) { 1837*0Sstevel@tonic-gate if (strcmp(l_scns->scn_name, ".lib") == 0) { 1838*0Sstevel@tonic-gate print_static(l_scns, filename); 1839*0Sstevel@tonic-gate } 1840*0Sstevel@tonic-gate l_scns++; 1841*0Sstevel@tonic-gate } 1842*0Sstevel@tonic-gate } 1843*0Sstevel@tonic-gate header_num++; 1844*0Sstevel@tonic-gate } 1845*0Sstevel@tonic-gate } 1846*0Sstevel@tonic-gate 1847*0Sstevel@tonic-gate /* 1848*0Sstevel@tonic-gate * Print the ELF header. Input is an ELF file descriptor 1849*0Sstevel@tonic-gate * and the filename. If f_flag is set, the ELF header is 1850*0Sstevel@tonic-gate * printed to stdout, otherwise the function returns after 1851*0Sstevel@tonic-gate * setting the pointer to the ELF header. Any values which 1852*0Sstevel@tonic-gate * are not known are printed in decimal. Fields must be updated 1853*0Sstevel@tonic-gate * as new values are added. 1854*0Sstevel@tonic-gate */ 1855*0Sstevel@tonic-gate static GElf_Ehdr * 1856*0Sstevel@tonic-gate dump_elf_header(Elf *elf_file, char *filename, GElf_Ehdr * elf_head_p) 1857*0Sstevel@tonic-gate { 1858*0Sstevel@tonic-gate int class, data; 1859*0Sstevel@tonic-gate int field; 1860*0Sstevel@tonic-gate 1861*0Sstevel@tonic-gate if (gelf_getehdr(elf_file, elf_head_p) == NULL) { 1862*0Sstevel@tonic-gate (void) fprintf(stderr, 1863*0Sstevel@tonic-gate "%s: %s: %s\n", prog_name, filename, elf_errmsg(-1)); 1864*0Sstevel@tonic-gate return (NULL); 1865*0Sstevel@tonic-gate } 1866*0Sstevel@tonic-gate 1867*0Sstevel@tonic-gate class = (int)elf_head_p->e_ident[4]; 1868*0Sstevel@tonic-gate 1869*0Sstevel@tonic-gate if (class == ELFCLASS64) 1870*0Sstevel@tonic-gate field = 17; 1871*0Sstevel@tonic-gate else 1872*0Sstevel@tonic-gate field = 13; 1873*0Sstevel@tonic-gate 1874*0Sstevel@tonic-gate if (!f_flag) 1875*0Sstevel@tonic-gate return (elf_head_p); 1876*0Sstevel@tonic-gate 1877*0Sstevel@tonic-gate if (!p_flag) { 1878*0Sstevel@tonic-gate (void) printf( 1879*0Sstevel@tonic-gate "\n **** ELF HEADER ****\n"); 1880*0Sstevel@tonic-gate (void) printf("%-*s%-11s%-*sMachine Version\n", 1881*0Sstevel@tonic-gate field, "Class", "Data", field, "Type"); 1882*0Sstevel@tonic-gate (void) printf("%-*s%-11s%-*sFlags Ehsize\n", 1883*0Sstevel@tonic-gate field, "Entry", "Phoff", field, "Shoff"); 1884*0Sstevel@tonic-gate (void) printf("%-*s%-11s%-*sShnum Shstrndx\n\n", 1885*0Sstevel@tonic-gate field, "Phentsize", "Phnum", field, "Shentsz"); 1886*0Sstevel@tonic-gate } 1887*0Sstevel@tonic-gate 1888*0Sstevel@tonic-gate if (!v_flag) { 1889*0Sstevel@tonic-gate (void) printf("%-*d%-11d%-*d%-12d%d\n", 1890*0Sstevel@tonic-gate field, elf_head_p->e_ident[4], 1891*0Sstevel@tonic-gate elf_head_p->e_ident[5], 1892*0Sstevel@tonic-gate field, (int)elf_head_p->e_type, 1893*0Sstevel@tonic-gate (int)elf_head_p->e_machine, 1894*0Sstevel@tonic-gate elf_head_p->e_version); 1895*0Sstevel@tonic-gate } else { 1896*0Sstevel@tonic-gate data = elf_head_p->e_ident[5]; 1897*0Sstevel@tonic-gate 1898*0Sstevel@tonic-gate switch (class) { 1899*0Sstevel@tonic-gate case ELFCLASSNONE: 1900*0Sstevel@tonic-gate (void) printf("%-*s", field, "None"); 1901*0Sstevel@tonic-gate break; 1902*0Sstevel@tonic-gate case ELFCLASS32: 1903*0Sstevel@tonic-gate (void) printf("%-*s", field, "32-bit"); 1904*0Sstevel@tonic-gate break; 1905*0Sstevel@tonic-gate case ELFCLASS64: 1906*0Sstevel@tonic-gate (void) printf("%-*s", field, "64-bit"); 1907*0Sstevel@tonic-gate break; 1908*0Sstevel@tonic-gate default: 1909*0Sstevel@tonic-gate (void) printf("%-*d", field, class); 1910*0Sstevel@tonic-gate break; 1911*0Sstevel@tonic-gate } 1912*0Sstevel@tonic-gate switch (data) { 1913*0Sstevel@tonic-gate case ELFDATANONE: 1914*0Sstevel@tonic-gate (void) printf("%-11s", "None "); 1915*0Sstevel@tonic-gate break; 1916*0Sstevel@tonic-gate case ELFDATA2LSB: 1917*0Sstevel@tonic-gate (void) printf("%-11s", "2LSB "); 1918*0Sstevel@tonic-gate break; 1919*0Sstevel@tonic-gate case ELFDATA2MSB: 1920*0Sstevel@tonic-gate (void) printf("%-11s", "2MSB "); 1921*0Sstevel@tonic-gate break; 1922*0Sstevel@tonic-gate default: 1923*0Sstevel@tonic-gate (void) printf("%-11d", data); 1924*0Sstevel@tonic-gate break; 1925*0Sstevel@tonic-gate } 1926*0Sstevel@tonic-gate 1927*0Sstevel@tonic-gate switch (elf_head_p->e_type) { 1928*0Sstevel@tonic-gate case ET_NONE: 1929*0Sstevel@tonic-gate (void) printf("%-*s", field, "None"); 1930*0Sstevel@tonic-gate break; 1931*0Sstevel@tonic-gate case ET_REL: 1932*0Sstevel@tonic-gate (void) printf("%-*s", field, "Reloc"); 1933*0Sstevel@tonic-gate break; 1934*0Sstevel@tonic-gate case ET_EXEC: 1935*0Sstevel@tonic-gate (void) printf("%-*s", field, "Exec"); 1936*0Sstevel@tonic-gate break; 1937*0Sstevel@tonic-gate case ET_DYN: 1938*0Sstevel@tonic-gate (void) printf("%-*s", field, "Dyn"); 1939*0Sstevel@tonic-gate break; 1940*0Sstevel@tonic-gate case ET_CORE: 1941*0Sstevel@tonic-gate (void) printf("%-*s", field, "Core"); 1942*0Sstevel@tonic-gate break; 1943*0Sstevel@tonic-gate default: 1944*0Sstevel@tonic-gate (void) printf("%-*d", field, 1945*0Sstevel@tonic-gate EC_WORD(elf_head_p->e_type)); 1946*0Sstevel@tonic-gate break; 1947*0Sstevel@tonic-gate } 1948*0Sstevel@tonic-gate switch (elf_head_p->e_machine) { 1949*0Sstevel@tonic-gate case EM_NONE: 1950*0Sstevel@tonic-gate (void) printf("%-12s", "No mach"); 1951*0Sstevel@tonic-gate break; 1952*0Sstevel@tonic-gate case EM_M32: 1953*0Sstevel@tonic-gate (void) printf("%-12s", "WE32100"); 1954*0Sstevel@tonic-gate break; 1955*0Sstevel@tonic-gate case EM_SPARC: 1956*0Sstevel@tonic-gate (void) printf("%-12s", "SPARC"); 1957*0Sstevel@tonic-gate break; 1958*0Sstevel@tonic-gate case EM_SPARCV9: 1959*0Sstevel@tonic-gate (void) printf("%-12s", "SPARCV9"); 1960*0Sstevel@tonic-gate break; 1961*0Sstevel@tonic-gate case EM_386: 1962*0Sstevel@tonic-gate (void) printf("%-12s", "80386"); 1963*0Sstevel@tonic-gate break; 1964*0Sstevel@tonic-gate case EM_68K: 1965*0Sstevel@tonic-gate (void) printf("%-12s", "68000"); 1966*0Sstevel@tonic-gate break; 1967*0Sstevel@tonic-gate case EM_88K: 1968*0Sstevel@tonic-gate (void) printf("%-12s", "88000"); 1969*0Sstevel@tonic-gate break; 1970*0Sstevel@tonic-gate case EM_486: 1971*0Sstevel@tonic-gate (void) printf("%-12s", "80486"); 1972*0Sstevel@tonic-gate break; 1973*0Sstevel@tonic-gate case EM_860: 1974*0Sstevel@tonic-gate (void) printf("%-12s", "i860"); 1975*0Sstevel@tonic-gate break; 1976*0Sstevel@tonic-gate case EM_MIPS: 1977*0Sstevel@tonic-gate (void) printf("%-12s", "RS3000_BE"); 1978*0Sstevel@tonic-gate break; 1979*0Sstevel@tonic-gate case EM_MIPS_RS3_LE: 1980*0Sstevel@tonic-gate (void) printf("%-12s", "RS3000_LE"); 1981*0Sstevel@tonic-gate break; 1982*0Sstevel@tonic-gate case EM_RS6000: 1983*0Sstevel@tonic-gate (void) printf("%-12s", "RS6000"); 1984*0Sstevel@tonic-gate break; 1985*0Sstevel@tonic-gate case EM_PA_RISC: 1986*0Sstevel@tonic-gate (void) printf("%-12s", "PA_RISC"); 1987*0Sstevel@tonic-gate break; 1988*0Sstevel@tonic-gate case EM_nCUBE: 1989*0Sstevel@tonic-gate (void) printf("%-12s", "nCUBE"); 1990*0Sstevel@tonic-gate break; 1991*0Sstevel@tonic-gate case EM_VPP500: 1992*0Sstevel@tonic-gate (void) printf("%-12s", "VPP500"); 1993*0Sstevel@tonic-gate break; 1994*0Sstevel@tonic-gate case EM_SPARC32PLUS: 1995*0Sstevel@tonic-gate (void) printf("%-12s", "SPARC32PLUS"); 1996*0Sstevel@tonic-gate break; 1997*0Sstevel@tonic-gate case EM_PPC: 1998*0Sstevel@tonic-gate (void) printf("%-12s", "PowerPC"); 1999*0Sstevel@tonic-gate break; 2000*0Sstevel@tonic-gate case EM_IA_64: 2001*0Sstevel@tonic-gate (void) printf("%-12s", "IA64"); 2002*0Sstevel@tonic-gate break; 2003*0Sstevel@tonic-gate default: 2004*0Sstevel@tonic-gate (void) printf("%-12d", EC_WORD(elf_head_p->e_machine)); 2005*0Sstevel@tonic-gate } 2006*0Sstevel@tonic-gate switch (elf_head_p->e_version) { 2007*0Sstevel@tonic-gate case EV_NONE: 2008*0Sstevel@tonic-gate (void) printf("Invalid\n"); 2009*0Sstevel@tonic-gate break; 2010*0Sstevel@tonic-gate case EV_CURRENT: 2011*0Sstevel@tonic-gate (void) printf("Current\n"); 2012*0Sstevel@tonic-gate break; 2013*0Sstevel@tonic-gate default: 2014*0Sstevel@tonic-gate (void) printf("%d\n", elf_head_p->e_version); 2015*0Sstevel@tonic-gate } 2016*0Sstevel@tonic-gate } 2017*0Sstevel@tonic-gate (void) printf("%-#*llx%-#11llx%-#*llx%-#12x%#x\n", 2018*0Sstevel@tonic-gate field, EC_ADDR(elf_head_p->e_entry), 2019*0Sstevel@tonic-gate EC_OFF(elf_head_p->e_phoff), 2020*0Sstevel@tonic-gate field, EC_OFF(elf_head_p->e_shoff), 2021*0Sstevel@tonic-gate EC_WORD(elf_head_p->e_flags), 2022*0Sstevel@tonic-gate EC_WORD(elf_head_p->e_ehsize)); 2023*0Sstevel@tonic-gate if (!v_flag || (elf_head_p->e_shstrndx != SHN_XINDEX)) { 2024*0Sstevel@tonic-gate (void) printf("%-#*x%-11u%-#*x%-12u%u\n", 2025*0Sstevel@tonic-gate field, EC_WORD(elf_head_p->e_phentsize), 2026*0Sstevel@tonic-gate EC_WORD(elf_head_p->e_phnum), 2027*0Sstevel@tonic-gate field, EC_WORD(elf_head_p->e_shentsize), 2028*0Sstevel@tonic-gate EC_WORD(elf_head_p->e_shnum), 2029*0Sstevel@tonic-gate EC_WORD(elf_head_p->e_shstrndx)); 2030*0Sstevel@tonic-gate } else { 2031*0Sstevel@tonic-gate (void) printf("%-#*x%-11u%-#*x%-12uXINDEX\n", 2032*0Sstevel@tonic-gate field, EC_WORD(elf_head_p->e_phentsize), 2033*0Sstevel@tonic-gate EC_WORD(elf_head_p->e_phnum), 2034*0Sstevel@tonic-gate field, EC_WORD(elf_head_p->e_shentsize), 2035*0Sstevel@tonic-gate EC_WORD(elf_head_p->e_shnum)); 2036*0Sstevel@tonic-gate } 2037*0Sstevel@tonic-gate if ((elf_head_p->e_shnum == 0) && (elf_head_p->e_shoff > 0)) { 2038*0Sstevel@tonic-gate Elf_Scn *scn; 2039*0Sstevel@tonic-gate GElf_Shdr shdr0; 2040*0Sstevel@tonic-gate int field; 2041*0Sstevel@tonic-gate 2042*0Sstevel@tonic-gate if (gelf_getclass(elf_file) == ELFCLASS64) 2043*0Sstevel@tonic-gate field = 14; 2044*0Sstevel@tonic-gate else 2045*0Sstevel@tonic-gate field = 12; 2046*0Sstevel@tonic-gate if (!p_flag) { 2047*0Sstevel@tonic-gate (void) printf("\n **** SECTION HEADER[0] " 2048*0Sstevel@tonic-gate "{Elf Extensions} ****\n"); 2049*0Sstevel@tonic-gate (void) printf( 2050*0Sstevel@tonic-gate "[No]\tType\tFlags\t%-*s %-*s%-*s%sName\n", 2051*0Sstevel@tonic-gate field, "Addr", field, "Offset", field, 2052*0Sstevel@tonic-gate "Size(shnum)", 2053*0Sstevel@tonic-gate /* compatibility: tab for elf32 */ 2054*0Sstevel@tonic-gate (field == 12) ? "\t" : " "); 2055*0Sstevel@tonic-gate (void) printf("\tLn(strndx) Info\t%-*s Entsize\n", 2056*0Sstevel@tonic-gate field, "Adralgn"); 2057*0Sstevel@tonic-gate } 2058*0Sstevel@tonic-gate if ((scn = elf_getscn(elf_file, 0)) == NULL) { 2059*0Sstevel@tonic-gate (void) fprintf(stderr, 2060*0Sstevel@tonic-gate "%s: %s: elf_getscn failed: %s\n", 2061*0Sstevel@tonic-gate prog_name, filename, elf_errmsg(-1)); 2062*0Sstevel@tonic-gate return (NULL); 2063*0Sstevel@tonic-gate } 2064*0Sstevel@tonic-gate if (gelf_getshdr(scn, &shdr0) == 0) { 2065*0Sstevel@tonic-gate (void) fprintf(stderr, 2066*0Sstevel@tonic-gate "%s: %s: gelf_getshdr: %s\n", 2067*0Sstevel@tonic-gate prog_name, filename, elf_errmsg(-1)); 2068*0Sstevel@tonic-gate return (NULL); 2069*0Sstevel@tonic-gate } 2070*0Sstevel@tonic-gate (void) printf("[0]\t%u\t%llu\t", EC_WORD(shdr0.sh_type), 2071*0Sstevel@tonic-gate EC_XWORD(shdr0.sh_flags)); 2072*0Sstevel@tonic-gate 2073*0Sstevel@tonic-gate /* 2074*0Sstevel@tonic-gate * LINTED - field and EC_XWORD cause -#*llu complaints that 2075*0Sstevel@tonic-gate * even this comment can't shutup. 2076*0Sstevel@tonic-gate */ 2077*0Sstevel@tonic-gate (void) printf("%-#*llx %-#*llx%-#*llu%s%-#*u\n", 2078*0Sstevel@tonic-gate field, EC_ADDR(shdr0.sh_addr), 2079*0Sstevel@tonic-gate field, EC_OFF(shdr0.sh_offset), 2080*0Sstevel@tonic-gate field, EC_XWORD(shdr0.sh_size), 2081*0Sstevel@tonic-gate /* compatibility: tab for elf32 */ 2082*0Sstevel@tonic-gate ((field == 12) ? "\t" : " "), 2083*0Sstevel@tonic-gate field, EC_WORD(shdr0.sh_name)); 2084*0Sstevel@tonic-gate 2085*0Sstevel@tonic-gate (void) printf("\t%u\t%u\t%-#*llx %-#*llx\n", 2086*0Sstevel@tonic-gate EC_WORD(shdr0.sh_link), 2087*0Sstevel@tonic-gate EC_WORD(shdr0.sh_info), 2088*0Sstevel@tonic-gate field, EC_XWORD(shdr0.sh_addralign), 2089*0Sstevel@tonic-gate field, EC_XWORD(shdr0.sh_entsize)); 2090*0Sstevel@tonic-gate } 2091*0Sstevel@tonic-gate (void) printf("\n"); 2092*0Sstevel@tonic-gate 2093*0Sstevel@tonic-gate return (elf_head_p); 2094*0Sstevel@tonic-gate } 2095*0Sstevel@tonic-gate 2096*0Sstevel@tonic-gate /* 2097*0Sstevel@tonic-gate * Print section contents. Input is an ELF file descriptor, 2098*0Sstevel@tonic-gate * the ELF header, the SCNTAB structure, 2099*0Sstevel@tonic-gate * the number of symbols, and the filename. 2100*0Sstevel@tonic-gate * The number of sections, 2101*0Sstevel@tonic-gate * and the offset into the SCNTAB structure will be 2102*0Sstevel@tonic-gate * set in dump_section if d_flag or n_flag are set. 2103*0Sstevel@tonic-gate * If v_flag is set, sections which can be interpreted will 2104*0Sstevel@tonic-gate * be interpreted, otherwise raw data will be output in hexidecimal. 2105*0Sstevel@tonic-gate */ 2106*0Sstevel@tonic-gate static void 2107*0Sstevel@tonic-gate print_section(Elf *elf_file, 2108*0Sstevel@tonic-gate GElf_Ehdr *p_ehdr, SCNTAB *p, int num_scns, char *filename) 2109*0Sstevel@tonic-gate { 2110*0Sstevel@tonic-gate unsigned char *p_sec; 2111*0Sstevel@tonic-gate int i; 2112*0Sstevel@tonic-gate size_t size; 2113*0Sstevel@tonic-gate 2114*0Sstevel@tonic-gate for (i = 0; i < num_scns; i++, p++) { 2115*0Sstevel@tonic-gate GElf_Shdr shdr; 2116*0Sstevel@tonic-gate 2117*0Sstevel@tonic-gate size = 0; 2118*0Sstevel@tonic-gate if (s_flag && !v_flag) 2119*0Sstevel@tonic-gate p_sec = (unsigned char *)get_rawscn(p->p_sd, &size); 2120*0Sstevel@tonic-gate else 2121*0Sstevel@tonic-gate p_sec = (unsigned char *)get_scndata(p->p_sd, &size); 2122*0Sstevel@tonic-gate 2123*0Sstevel@tonic-gate if ((gelf_getshdr(p->p_sd, &shdr) != NULL) && 2124*0Sstevel@tonic-gate (shdr.sh_type == SHT_NOBITS)) { 2125*0Sstevel@tonic-gate continue; 2126*0Sstevel@tonic-gate } 2127*0Sstevel@tonic-gate if (s_flag && !v_flag) { 2128*0Sstevel@tonic-gate (void) printf("\n%s:\n", p->scn_name); 2129*0Sstevel@tonic-gate print_rawdata(p_sec, size); 2130*0Sstevel@tonic-gate continue; 2131*0Sstevel@tonic-gate } 2132*0Sstevel@tonic-gate if (shdr.sh_type == SHT_SYMTAB) { 2133*0Sstevel@tonic-gate dump_symbol_table(elf_file, p, filename); 2134*0Sstevel@tonic-gate continue; 2135*0Sstevel@tonic-gate } 2136*0Sstevel@tonic-gate if (shdr.sh_type == SHT_DYNSYM) { 2137*0Sstevel@tonic-gate dump_symbol_table(elf_file, p, filename); 2138*0Sstevel@tonic-gate continue; 2139*0Sstevel@tonic-gate } 2140*0Sstevel@tonic-gate if (shdr.sh_type == SHT_STRTAB) { 2141*0Sstevel@tonic-gate dump_string_table(p, 1); 2142*0Sstevel@tonic-gate continue; 2143*0Sstevel@tonic-gate } 2144*0Sstevel@tonic-gate if (shdr.sh_type == SHT_RELA) { 2145*0Sstevel@tonic-gate dump_reloc_table(elf_file, p_ehdr, p, 1, filename); 2146*0Sstevel@tonic-gate continue; 2147*0Sstevel@tonic-gate } 2148*0Sstevel@tonic-gate if (shdr.sh_type == SHT_REL) { 2149*0Sstevel@tonic-gate dump_reloc_table(elf_file, p_ehdr, p, 1, filename); 2150*0Sstevel@tonic-gate continue; 2151*0Sstevel@tonic-gate } 2152*0Sstevel@tonic-gate if (shdr.sh_type == SHT_DYNAMIC) { 2153*0Sstevel@tonic-gate dump_dynamic(elf_file, p, 1, filename); 2154*0Sstevel@tonic-gate continue; 2155*0Sstevel@tonic-gate } 2156*0Sstevel@tonic-gate 2157*0Sstevel@tonic-gate (void) printf("\n%s:\n", p->scn_name); 2158*0Sstevel@tonic-gate print_rawdata(p_sec, size); 2159*0Sstevel@tonic-gate } 2160*0Sstevel@tonic-gate (void) printf("\n"); 2161*0Sstevel@tonic-gate } 2162*0Sstevel@tonic-gate 2163*0Sstevel@tonic-gate /* 2164*0Sstevel@tonic-gate * Print section contents. This function does not print the contents 2165*0Sstevel@tonic-gate * of the sections but sets up the parameters and then calls 2166*0Sstevel@tonic-gate * print_section to print the contents. Calling another function to print 2167*0Sstevel@tonic-gate * the contents allows both -d and -n to work correctly 2168*0Sstevel@tonic-gate * simultaneously. Input is an ELF file descriptor, the ELF header, 2169*0Sstevel@tonic-gate * the SCNTAB structure, the number of sections, and the filename. 2170*0Sstevel@tonic-gate * Set the range of sections if d_flag, and set section name if 2171*0Sstevel@tonic-gate * n_flag. 2172*0Sstevel@tonic-gate */ 2173*0Sstevel@tonic-gate static void 2174*0Sstevel@tonic-gate dump_section(Elf *elf_file, 2175*0Sstevel@tonic-gate GElf_Ehdr *p_ehdr, SCNTAB *s, int num_scns, char *filename) 2176*0Sstevel@tonic-gate { 2177*0Sstevel@tonic-gate SCNTAB *n_range, *d_range; /* for use with -n and -d modifiers */ 2178*0Sstevel@tonic-gate int i; 2179*0Sstevel@tonic-gate int found_it = 0; /* for use with -n section_name */ 2180*0Sstevel@tonic-gate 2181*0Sstevel@tonic-gate if (n_flag) { 2182*0Sstevel@tonic-gate n_range = s; 2183*0Sstevel@tonic-gate 2184*0Sstevel@tonic-gate for (i = 0; i < num_scns; i++, n_range++) { 2185*0Sstevel@tonic-gate if ((strcmp(name, n_range->scn_name)) != 0) 2186*0Sstevel@tonic-gate continue; 2187*0Sstevel@tonic-gate else { 2188*0Sstevel@tonic-gate found_it = 1; 2189*0Sstevel@tonic-gate print_section(elf_file, p_ehdr, 2190*0Sstevel@tonic-gate n_range, 1, filename); 2191*0Sstevel@tonic-gate } 2192*0Sstevel@tonic-gate } 2193*0Sstevel@tonic-gate 2194*0Sstevel@tonic-gate if (!found_it) { 2195*0Sstevel@tonic-gate (void) fprintf(stderr, "%s: %s: %s not found\n", 2196*0Sstevel@tonic-gate prog_name, filename, name); 2197*0Sstevel@tonic-gate } 2198*0Sstevel@tonic-gate } /* end n_flag */ 2199*0Sstevel@tonic-gate 2200*0Sstevel@tonic-gate if (d_flag) { 2201*0Sstevel@tonic-gate d_range = s; 2202*0Sstevel@tonic-gate d_num = check_range(d_low, d_hi, num_scns, filename); 2203*0Sstevel@tonic-gate if (d_num < 0) 2204*0Sstevel@tonic-gate return; 2205*0Sstevel@tonic-gate d_range += d_low - 1; 2206*0Sstevel@tonic-gate 2207*0Sstevel@tonic-gate print_section(elf_file, p_ehdr, d_range, d_num, filename); 2208*0Sstevel@tonic-gate } /* end d_flag */ 2209*0Sstevel@tonic-gate 2210*0Sstevel@tonic-gate if (!n_flag && !d_flag) 2211*0Sstevel@tonic-gate print_section(elf_file, p_ehdr, s, num_scns, filename); 2212*0Sstevel@tonic-gate } 2213*0Sstevel@tonic-gate 2214*0Sstevel@tonic-gate /* 2215*0Sstevel@tonic-gate * Print the section header table. This function does not print the contents 2216*0Sstevel@tonic-gate * of the section headers but sets up the parameters and then calls 2217*0Sstevel@tonic-gate * print_shdr to print the contents. Calling another function to print 2218*0Sstevel@tonic-gate * the contents allows both -d and -n to work correctly 2219*0Sstevel@tonic-gate * simultaneously. Input is the SCNTAB structure, 2220*0Sstevel@tonic-gate * the number of sections from the ELF header, and the filename. 2221*0Sstevel@tonic-gate * Set the range of section headers to print if d_flag, and set 2222*0Sstevel@tonic-gate * name of section header to print if n_flag. 2223*0Sstevel@tonic-gate */ 2224*0Sstevel@tonic-gate static void 2225*0Sstevel@tonic-gate dump_shdr(Elf *elf_file, SCNTAB *s, int num_scns, char *filename) 2226*0Sstevel@tonic-gate { 2227*0Sstevel@tonic-gate 2228*0Sstevel@tonic-gate SCNTAB *n_range, *d_range; /* for use with -n and -d modifiers */ 2229*0Sstevel@tonic-gate int field; 2230*0Sstevel@tonic-gate int i; 2231*0Sstevel@tonic-gate int found_it = 0; /* for use with -n section_name */ 2232*0Sstevel@tonic-gate 2233*0Sstevel@tonic-gate if (gelf_getclass(elf_file) == ELFCLASS64) 2234*0Sstevel@tonic-gate field = 14; 2235*0Sstevel@tonic-gate else 2236*0Sstevel@tonic-gate field = 12; 2237*0Sstevel@tonic-gate 2238*0Sstevel@tonic-gate if (!p_flag) { 2239*0Sstevel@tonic-gate (void) printf("\n **** SECTION HEADER TABLE ****\n"); 2240*0Sstevel@tonic-gate (void) printf("[No]\tType\tFlags\t%-*s %-*s %-*s%sName\n", 2241*0Sstevel@tonic-gate field, "Addr", field, "Offset", field, "Size", 2242*0Sstevel@tonic-gate /* compatibility: tab for elf32 */ 2243*0Sstevel@tonic-gate (field == 12) ? "\t" : " "); 2244*0Sstevel@tonic-gate (void) printf("\tLink\tInfo\t%-*s Entsize\n\n", 2245*0Sstevel@tonic-gate field, "Adralgn"); 2246*0Sstevel@tonic-gate } 2247*0Sstevel@tonic-gate 2248*0Sstevel@tonic-gate if (n_flag) { 2249*0Sstevel@tonic-gate n_range = s; 2250*0Sstevel@tonic-gate 2251*0Sstevel@tonic-gate for (i = 1; i <= num_scns; i++, n_range++) { 2252*0Sstevel@tonic-gate if ((strcmp(name, n_range->scn_name)) != 0) 2253*0Sstevel@tonic-gate continue; 2254*0Sstevel@tonic-gate else { 2255*0Sstevel@tonic-gate found_it = 1; 2256*0Sstevel@tonic-gate print_shdr(elf_file, n_range, 1, i); 2257*0Sstevel@tonic-gate } 2258*0Sstevel@tonic-gate } 2259*0Sstevel@tonic-gate 2260*0Sstevel@tonic-gate if (!found_it) { 2261*0Sstevel@tonic-gate (void) fprintf(stderr, "%s: %s: %s not found\n", 2262*0Sstevel@tonic-gate prog_name, filename, name); 2263*0Sstevel@tonic-gate } 2264*0Sstevel@tonic-gate } /* end n_flag */ 2265*0Sstevel@tonic-gate 2266*0Sstevel@tonic-gate if (d_flag) { 2267*0Sstevel@tonic-gate d_range = s; 2268*0Sstevel@tonic-gate d_num = check_range(d_low, d_hi, num_scns, filename); 2269*0Sstevel@tonic-gate if (d_num < 0) 2270*0Sstevel@tonic-gate return; 2271*0Sstevel@tonic-gate d_range += d_low - 1; 2272*0Sstevel@tonic-gate 2273*0Sstevel@tonic-gate print_shdr(elf_file, d_range, d_num, d_low); 2274*0Sstevel@tonic-gate } /* end d_flag */ 2275*0Sstevel@tonic-gate 2276*0Sstevel@tonic-gate if (!n_flag && !d_flag) 2277*0Sstevel@tonic-gate print_shdr(elf_file, s, num_scns, 1); 2278*0Sstevel@tonic-gate } 2279*0Sstevel@tonic-gate 2280*0Sstevel@tonic-gate /* 2281*0Sstevel@tonic-gate * Process all of the command line options (except 2282*0Sstevel@tonic-gate * for -a, -g, -f, and -o). All of the options processed 2283*0Sstevel@tonic-gate * by this function require the presence of the section 2284*0Sstevel@tonic-gate * header table and will not be processed if it is not present. 2285*0Sstevel@tonic-gate * Set up a buffer containing section name, section header, 2286*0Sstevel@tonic-gate * and section descriptor for each section in the file. This 2287*0Sstevel@tonic-gate * structure is used to avoid duplicate calls to libelf functions. 2288*0Sstevel@tonic-gate * Structure members for the symbol table, the debugging information, 2289*0Sstevel@tonic-gate * and the line number information are global. All of the 2290*0Sstevel@tonic-gate * rest are local. 2291*0Sstevel@tonic-gate */ 2292*0Sstevel@tonic-gate static void 2293*0Sstevel@tonic-gate dump_section_table(Elf *elf_file, GElf_Ehdr *elf_head_p, char *filename) 2294*0Sstevel@tonic-gate { 2295*0Sstevel@tonic-gate 2296*0Sstevel@tonic-gate static SCNTAB *buffer, *p_scns; 2297*0Sstevel@tonic-gate Elf_Scn *scn = 0; 2298*0Sstevel@tonic-gate char *s_name = NULL; 2299*0Sstevel@tonic-gate int found = 0; 2300*0Sstevel@tonic-gate unsigned int num_scns; 2301*0Sstevel@tonic-gate size_t shstrndx; 2302*0Sstevel@tonic-gate size_t shnum; 2303*0Sstevel@tonic-gate 2304*0Sstevel@tonic-gate 2305*0Sstevel@tonic-gate if (elf_getshnum(elf_file, &shnum) == 0) { 2306*0Sstevel@tonic-gate (void) fprintf(stderr, 2307*0Sstevel@tonic-gate "%s: %s: elf_getshnum failed: %s\n", 2308*0Sstevel@tonic-gate prog_name, filename, elf_errmsg(-1)); 2309*0Sstevel@tonic-gate return; 2310*0Sstevel@tonic-gate } 2311*0Sstevel@tonic-gate if (elf_getshstrndx(elf_file, &shstrndx) == 0) { 2312*0Sstevel@tonic-gate (void) fprintf(stderr, 2313*0Sstevel@tonic-gate "%s: %s: elf_getshstrndx failed: %s\n", 2314*0Sstevel@tonic-gate prog_name, filename, elf_errmsg(-1)); 2315*0Sstevel@tonic-gate return; 2316*0Sstevel@tonic-gate } 2317*0Sstevel@tonic-gate 2318*0Sstevel@tonic-gate if ((buffer = calloc(shnum, sizeof (SCNTAB))) == NULL) { 2319*0Sstevel@tonic-gate (void) fprintf(stderr, "%s: %s: cannot calloc space\n", 2320*0Sstevel@tonic-gate prog_name, filename); 2321*0Sstevel@tonic-gate return; 2322*0Sstevel@tonic-gate } 2323*0Sstevel@tonic-gate /* LINTED */ 2324*0Sstevel@tonic-gate num_scns = (int)shnum - 1; 2325*0Sstevel@tonic-gate 2326*0Sstevel@tonic-gate p_symtab = (SCNTAB *)0; 2327*0Sstevel@tonic-gate p_dynsym = (SCNTAB *)0; 2328*0Sstevel@tonic-gate p_scns = buffer; 2329*0Sstevel@tonic-gate p_head_scns = buffer; 2330*0Sstevel@tonic-gate 2331*0Sstevel@tonic-gate while ((scn = elf_nextscn(elf_file, scn)) != 0) { 2332*0Sstevel@tonic-gate if ((gelf_getshdr(scn, &buffer->p_shdr)) == 0) { 2333*0Sstevel@tonic-gate (void) fprintf(stderr, 2334*0Sstevel@tonic-gate "%s: %s: %s\n", prog_name, filename, elf_errmsg(-1)); 2335*0Sstevel@tonic-gate return; 2336*0Sstevel@tonic-gate } 2337*0Sstevel@tonic-gate s_name = (char *)elf_strptr(elf_file, 2338*0Sstevel@tonic-gate shstrndx, buffer->p_shdr.sh_name); 2339*0Sstevel@tonic-gate buffer->scn_name = s_name ? s_name : (char *)UNKNOWN; 2340*0Sstevel@tonic-gate buffer->p_sd = scn; 2341*0Sstevel@tonic-gate 2342*0Sstevel@tonic-gate if (buffer->p_shdr.sh_type == SHT_SYMTAB) { 2343*0Sstevel@tonic-gate found += 1; 2344*0Sstevel@tonic-gate p_symtab = buffer; 2345*0Sstevel@tonic-gate } 2346*0Sstevel@tonic-gate if (buffer->p_shdr.sh_type == SHT_DYNSYM) 2347*0Sstevel@tonic-gate p_dynsym = buffer; 2348*0Sstevel@tonic-gate buffer++; 2349*0Sstevel@tonic-gate } 2350*0Sstevel@tonic-gate 2351*0Sstevel@tonic-gate /* 2352*0Sstevel@tonic-gate * These functions depend upon the presence of the section header table 2353*0Sstevel@tonic-gate * and will not be invoked in its absence 2354*0Sstevel@tonic-gate */ 2355*0Sstevel@tonic-gate if (h_flag) { 2356*0Sstevel@tonic-gate dump_shdr(elf_file, p_scns, num_scns, filename); 2357*0Sstevel@tonic-gate } 2358*0Sstevel@tonic-gate if (p_symtab && (t_flag || T_flag)) { 2359*0Sstevel@tonic-gate dump_symbol_table(elf_file, p_symtab, filename); 2360*0Sstevel@tonic-gate } 2361*0Sstevel@tonic-gate if (c_flag) { 2362*0Sstevel@tonic-gate dump_string_table(p_scns, num_scns); 2363*0Sstevel@tonic-gate } 2364*0Sstevel@tonic-gate if (r_flag) { 2365*0Sstevel@tonic-gate dump_reloc_table(elf_file, elf_head_p, 2366*0Sstevel@tonic-gate p_scns, num_scns, filename); 2367*0Sstevel@tonic-gate } 2368*0Sstevel@tonic-gate if (L_flag) { 2369*0Sstevel@tonic-gate dump_dynamic(elf_file, p_scns, num_scns, filename); 2370*0Sstevel@tonic-gate } 2371*0Sstevel@tonic-gate if (s_flag) { 2372*0Sstevel@tonic-gate dump_section(elf_file, elf_head_p, p_scns, 2373*0Sstevel@tonic-gate num_scns, filename); 2374*0Sstevel@tonic-gate } 2375*0Sstevel@tonic-gate } 2376*0Sstevel@tonic-gate 2377*0Sstevel@tonic-gate /* 2378*0Sstevel@tonic-gate * Load the archive string table(s) (for extended-length strings) 2379*0Sstevel@tonic-gate * into an in-core table/list 2380*0Sstevel@tonic-gate */ 2381*0Sstevel@tonic-gate static struct stab_list_s * 2382*0Sstevel@tonic-gate load_arstring_table(struct stab_list_s *STabList, 2383*0Sstevel@tonic-gate int fd, Elf *elf_file, Elf_Arhdr *p_ar, char *filename) 2384*0Sstevel@tonic-gate { 2385*0Sstevel@tonic-gate off_t here; 2386*0Sstevel@tonic-gate struct stab_list_s *STL_entry, *STL_next; 2387*0Sstevel@tonic-gate 2388*0Sstevel@tonic-gate if (p_ar) { 2389*0Sstevel@tonic-gate STL_entry = malloc(sizeof (struct stab_list_s)); 2390*0Sstevel@tonic-gate STL_entry->next = 0; 2391*0Sstevel@tonic-gate STL_entry->strings = 0; 2392*0Sstevel@tonic-gate STL_entry->size = 0; 2393*0Sstevel@tonic-gate 2394*0Sstevel@tonic-gate if (!STabList) 2395*0Sstevel@tonic-gate STabList = STL_entry; 2396*0Sstevel@tonic-gate else { 2397*0Sstevel@tonic-gate STL_next = STabList; 2398*0Sstevel@tonic-gate while (STL_next->next != (void *)0) 2399*0Sstevel@tonic-gate STL_next = STL_next->next; 2400*0Sstevel@tonic-gate STL_next->next = STL_entry; 2401*0Sstevel@tonic-gate } 2402*0Sstevel@tonic-gate 2403*0Sstevel@tonic-gate STL_entry->size = p_ar->ar_size; 2404*0Sstevel@tonic-gate STL_entry->strings = malloc(p_ar->ar_size); 2405*0Sstevel@tonic-gate here = elf_getbase(elf_file); 2406*0Sstevel@tonic-gate if ((lseek(fd, here, 0)) != here) { 2407*0Sstevel@tonic-gate (void) fprintf(stderr, 2408*0Sstevel@tonic-gate "%s: %s: could not lseek\n", prog_name, filename); 2409*0Sstevel@tonic-gate } 2410*0Sstevel@tonic-gate 2411*0Sstevel@tonic-gate if ((read(fd, STL_entry->strings, p_ar->ar_size)) == -1) { 2412*0Sstevel@tonic-gate (void) fprintf(stderr, 2413*0Sstevel@tonic-gate "%s: %s: could not read\n", prog_name, filename); 2414*0Sstevel@tonic-gate } 2415*0Sstevel@tonic-gate } 2416*0Sstevel@tonic-gate return (STabList); 2417*0Sstevel@tonic-gate } 2418*0Sstevel@tonic-gate 2419*0Sstevel@tonic-gate /* 2420*0Sstevel@tonic-gate * Print the archive header for each member of an archive. 2421*0Sstevel@tonic-gate * Also call ar_sym_read to print the symbols in the 2422*0Sstevel@tonic-gate * archive symbol table if g_flag. Input is a file descriptor, 2423*0Sstevel@tonic-gate * an ELF file descriptor, and the filename. Putting the call 2424*0Sstevel@tonic-gate * to dump the archive symbol table in this function is more 2425*0Sstevel@tonic-gate * efficient since it is necessary to examine the archive member 2426*0Sstevel@tonic-gate * name in the archive header to determine which member is the 2427*0Sstevel@tonic-gate * symbol table. 2428*0Sstevel@tonic-gate */ 2429*0Sstevel@tonic-gate static void 2430*0Sstevel@tonic-gate dump_ar_hdr(int fd, Elf *elf_file, char *filename) 2431*0Sstevel@tonic-gate { 2432*0Sstevel@tonic-gate extern int v_flag, g_flag, a_flag, p_flag; 2433*0Sstevel@tonic-gate Elf_Arhdr *p_ar; 2434*0Sstevel@tonic-gate Elf *arf; 2435*0Sstevel@tonic-gate Elf_Cmd cmd; 2436*0Sstevel@tonic-gate int title = 0; 2437*0Sstevel@tonic-gate int err = 0; 2438*0Sstevel@tonic-gate 2439*0Sstevel@tonic-gate char buf[DATESIZE]; 2440*0Sstevel@tonic-gate 2441*0Sstevel@tonic-gate cmd = ELF_C_READ; 2442*0Sstevel@tonic-gate while ((arf = elf_begin(fd, cmd, elf_file)) != 0) { 2443*0Sstevel@tonic-gate p_ar = elf_getarhdr(arf); 2444*0Sstevel@tonic-gate if (p_ar == NULL) { 2445*0Sstevel@tonic-gate (void) fprintf(stderr, 2446*0Sstevel@tonic-gate "%s: %s: %s\n", prog_name, filename, elf_errmsg(-1)); 2447*0Sstevel@tonic-gate continue; 2448*0Sstevel@tonic-gate } 2449*0Sstevel@tonic-gate if (strcmp(p_ar->ar_name, "/") == 0) { 2450*0Sstevel@tonic-gate if (g_flag) 2451*0Sstevel@tonic-gate ar_sym_read(elf_file, filename); 2452*0Sstevel@tonic-gate } else if (strcmp(p_ar->ar_name, "//") == 0) { 2453*0Sstevel@tonic-gate StringTableList = load_arstring_table( 2454*0Sstevel@tonic-gate StringTableList, fd, arf, p_ar, 2455*0Sstevel@tonic-gate filename); 2456*0Sstevel@tonic-gate cmd = elf_next(arf); 2457*0Sstevel@tonic-gate (void) elf_end(arf); 2458*0Sstevel@tonic-gate continue; 2459*0Sstevel@tonic-gate } else { 2460*0Sstevel@tonic-gate if (a_flag) { 2461*0Sstevel@tonic-gate (void) printf("%s[%s]:\n", filename, 2462*0Sstevel@tonic-gate p_ar->ar_name); 2463*0Sstevel@tonic-gate if (!p_flag && title == 0) { 2464*0Sstevel@tonic-gate if (!v_flag) 2465*0Sstevel@tonic-gate (void) printf( 2466*0Sstevel@tonic-gate "\n\n\t\t\t***ARCHIVE HEADER***" 2467*0Sstevel@tonic-gate "\n Date Uid Gid Mode Size Member Name\n\n"); 2468*0Sstevel@tonic-gate else 2469*0Sstevel@tonic-gate (void) printf( 2470*0Sstevel@tonic-gate "\n\n\t\t\t***ARCHIVE HEADER***" 2471*0Sstevel@tonic-gate "\n Date Uid Gid Mode Size Member Name\n\n"); 2472*0Sstevel@tonic-gate title = 1; 2473*0Sstevel@tonic-gate } 2474*0Sstevel@tonic-gate if (!v_flag) { 2475*0Sstevel@tonic-gate (void) printf( 2476*0Sstevel@tonic-gate "\t0x%.8lx %6d %6d 0%.6ho 0x%.8lx %-s\n\n", 2477*0Sstevel@tonic-gate p_ar->ar_date, 2478*0Sstevel@tonic-gate (int)p_ar->ar_uid, 2479*0Sstevel@tonic-gate (int)p_ar->ar_gid, 2480*0Sstevel@tonic-gate (int)p_ar->ar_mode, 2481*0Sstevel@tonic-gate p_ar->ar_size, 2482*0Sstevel@tonic-gate p_ar->ar_name); 2483*0Sstevel@tonic-gate } else { 2484*0Sstevel@tonic-gate if ((strftime(buf, DATESIZE, 2485*0Sstevel@tonic-gate "%b %d %H:%M:%S %Y", 2486*0Sstevel@tonic-gate localtime( 2487*0Sstevel@tonic-gate &(p_ar->ar_date)))) == 0) { 2488*0Sstevel@tonic-gate (void) fprintf(stderr, 2489*0Sstevel@tonic-gate "%s: %s: don't have enough space to store the date\n", prog_name, filename); 2490*0Sstevel@tonic-gate exit(1); 2491*0Sstevel@tonic-gate } 2492*0Sstevel@tonic-gate (void) printf( 2493*0Sstevel@tonic-gate "\t%s %6d %6d 0%.6ho 0x%.8lx %-s\n\n", 2494*0Sstevel@tonic-gate buf, 2495*0Sstevel@tonic-gate (int)p_ar->ar_uid, 2496*0Sstevel@tonic-gate (int)p_ar->ar_gid, 2497*0Sstevel@tonic-gate (int)p_ar->ar_mode, 2498*0Sstevel@tonic-gate p_ar->ar_size, 2499*0Sstevel@tonic-gate p_ar->ar_name); 2500*0Sstevel@tonic-gate } 2501*0Sstevel@tonic-gate } 2502*0Sstevel@tonic-gate } 2503*0Sstevel@tonic-gate cmd = elf_next(arf); 2504*0Sstevel@tonic-gate (void) elf_end(arf); 2505*0Sstevel@tonic-gate } /* end while */ 2506*0Sstevel@tonic-gate 2507*0Sstevel@tonic-gate err = elf_errno(); 2508*0Sstevel@tonic-gate if (err != 0) { 2509*0Sstevel@tonic-gate (void) fprintf(stderr, 2510*0Sstevel@tonic-gate "%s: %s: %s\n", prog_name, filename, elf_errmsg(err)); 2511*0Sstevel@tonic-gate } 2512*0Sstevel@tonic-gate } 2513*0Sstevel@tonic-gate 2514*0Sstevel@tonic-gate /* 2515*0Sstevel@tonic-gate * Process member files of an archive. This function provides 2516*0Sstevel@tonic-gate * a loop through an archive equivalent the processing of 2517*0Sstevel@tonic-gate * each_file for individual object files. 2518*0Sstevel@tonic-gate */ 2519*0Sstevel@tonic-gate static void 2520*0Sstevel@tonic-gate dump_ar_files(int fd, Elf *elf_file, char *filename) 2521*0Sstevel@tonic-gate { 2522*0Sstevel@tonic-gate Elf_Arhdr *p_ar; 2523*0Sstevel@tonic-gate Elf *arf; 2524*0Sstevel@tonic-gate Elf_Cmd cmd; 2525*0Sstevel@tonic-gate Elf_Kind file_type; 2526*0Sstevel@tonic-gate GElf_Ehdr elf_head; 2527*0Sstevel@tonic-gate char *fullname; 2528*0Sstevel@tonic-gate 2529*0Sstevel@tonic-gate cmd = ELF_C_READ; 2530*0Sstevel@tonic-gate while ((arf = elf_begin(fd, cmd, elf_file)) != 0) { 2531*0Sstevel@tonic-gate p_ar = elf_getarhdr(arf); 2532*0Sstevel@tonic-gate if (p_ar == NULL) { 2533*0Sstevel@tonic-gate (void) fprintf(stderr, 2534*0Sstevel@tonic-gate "%s: %s: %s\n", 2535*0Sstevel@tonic-gate prog_name, filename, elf_errmsg(-1)); 2536*0Sstevel@tonic-gate return; 2537*0Sstevel@tonic-gate } 2538*0Sstevel@tonic-gate if ((strcmp(p_ar->ar_name, "/") == 0) || 2539*0Sstevel@tonic-gate (strcmp(p_ar->ar_name, "//") == 0)) { 2540*0Sstevel@tonic-gate cmd = elf_next(arf); 2541*0Sstevel@tonic-gate (void) elf_end(arf); 2542*0Sstevel@tonic-gate continue; 2543*0Sstevel@tonic-gate } 2544*0Sstevel@tonic-gate 2545*0Sstevel@tonic-gate fullname = malloc(strlen(filename) + strlen(p_ar->ar_name) + 3); 2546*0Sstevel@tonic-gate (void) sprintf(fullname, "%s[%s]", filename, p_ar->ar_name); 2547*0Sstevel@tonic-gate (void) printf("\n%s:\n", fullname); 2548*0Sstevel@tonic-gate file_type = elf_kind(arf); 2549*0Sstevel@tonic-gate if (file_type == ELF_K_ELF) { 2550*0Sstevel@tonic-gate if (dump_elf_header(arf, fullname, &elf_head) == NULL) 2551*0Sstevel@tonic-gate return; 2552*0Sstevel@tonic-gate if (o_flag) 2553*0Sstevel@tonic-gate dump_exec_header(arf, 2554*0Sstevel@tonic-gate (unsigned)elf_head.e_phnum, fullname); 2555*0Sstevel@tonic-gate if (x_flag) 2556*0Sstevel@tonic-gate dump_section_table(arf, &elf_head, fullname); 2557*0Sstevel@tonic-gate } else { 2558*0Sstevel@tonic-gate (void) fprintf(stderr, 2559*0Sstevel@tonic-gate "%s: %s: invalid file type\n", 2560*0Sstevel@tonic-gate prog_name, fullname); 2561*0Sstevel@tonic-gate cmd = elf_next(arf); 2562*0Sstevel@tonic-gate (void) elf_end(arf); 2563*0Sstevel@tonic-gate continue; 2564*0Sstevel@tonic-gate } 2565*0Sstevel@tonic-gate 2566*0Sstevel@tonic-gate cmd = elf_next(arf); 2567*0Sstevel@tonic-gate (void) elf_end(arf); 2568*0Sstevel@tonic-gate } /* end while */ 2569*0Sstevel@tonic-gate } 2570*0Sstevel@tonic-gate 2571*0Sstevel@tonic-gate /* 2572*0Sstevel@tonic-gate * Takes a filename as input. Test first for a valid version 2573*0Sstevel@tonic-gate * of libelf.a and exit on error. Process each valid file 2574*0Sstevel@tonic-gate * or archive given as input on the command line. Check 2575*0Sstevel@tonic-gate * for file type. If it is an archive, process the archive- 2576*0Sstevel@tonic-gate * specific options first, then files within the archive. 2577*0Sstevel@tonic-gate * If it is an ELF object file, process it; otherwise 2578*0Sstevel@tonic-gate * warn that it is an invalid file type. 2579*0Sstevel@tonic-gate * All options except the archive-specific and program 2580*0Sstevel@tonic-gate * execution header are processed in the function, dump_section_table. 2581*0Sstevel@tonic-gate */ 2582*0Sstevel@tonic-gate static void 2583*0Sstevel@tonic-gate each_file(char *filename) 2584*0Sstevel@tonic-gate { 2585*0Sstevel@tonic-gate Elf *elf_file; 2586*0Sstevel@tonic-gate GElf_Ehdr elf_head; 2587*0Sstevel@tonic-gate int fd; 2588*0Sstevel@tonic-gate Elf_Kind file_type; 2589*0Sstevel@tonic-gate 2590*0Sstevel@tonic-gate struct stat buf; 2591*0Sstevel@tonic-gate 2592*0Sstevel@tonic-gate Elf_Cmd cmd; 2593*0Sstevel@tonic-gate errno = 0; 2594*0Sstevel@tonic-gate 2595*0Sstevel@tonic-gate if (stat(filename, &buf) == -1) { 2596*0Sstevel@tonic-gate (void) fprintf(stderr, "%s: ", prog_name); 2597*0Sstevel@tonic-gate perror(filename); 2598*0Sstevel@tonic-gate return; 2599*0Sstevel@tonic-gate } 2600*0Sstevel@tonic-gate 2601*0Sstevel@tonic-gate if (elf_version(EV_CURRENT) == EV_NONE) { 2602*0Sstevel@tonic-gate (void) fprintf(stderr, 2603*0Sstevel@tonic-gate "%s: Libelf is out of date\n", prog_name); 2604*0Sstevel@tonic-gate exit(101); 2605*0Sstevel@tonic-gate } 2606*0Sstevel@tonic-gate 2607*0Sstevel@tonic-gate if ((fd = open((filename), O_RDONLY)) == -1) { 2608*0Sstevel@tonic-gate (void) fprintf(stderr, "%s: %s: cannot read\n", 2609*0Sstevel@tonic-gate prog_name, filename); 2610*0Sstevel@tonic-gate return; 2611*0Sstevel@tonic-gate } 2612*0Sstevel@tonic-gate cmd = ELF_C_READ; 2613*0Sstevel@tonic-gate if ((elf_file = elf_begin(fd, cmd, (Elf *)0)) == NULL) { 2614*0Sstevel@tonic-gate (void) fprintf(stderr, 2615*0Sstevel@tonic-gate "%s: %s: %s\n", prog_name, filename, elf_errmsg(-1)); 2616*0Sstevel@tonic-gate return; 2617*0Sstevel@tonic-gate } 2618*0Sstevel@tonic-gate 2619*0Sstevel@tonic-gate file_type = elf_kind(elf_file); 2620*0Sstevel@tonic-gate if (file_type == ELF_K_AR) { 2621*0Sstevel@tonic-gate if (a_flag || g_flag) { 2622*0Sstevel@tonic-gate dump_ar_hdr(fd, elf_file, filename); 2623*0Sstevel@tonic-gate elf_file = elf_begin(fd, cmd, (Elf *)0); 2624*0Sstevel@tonic-gate } 2625*0Sstevel@tonic-gate if (z_flag) 2626*0Sstevel@tonic-gate dump_ar_files(fd, elf_file, filename); 2627*0Sstevel@tonic-gate } else { 2628*0Sstevel@tonic-gate if (file_type == ELF_K_ELF) { 2629*0Sstevel@tonic-gate (void) printf("\n%s:\n", filename); 2630*0Sstevel@tonic-gate if (dump_elf_header(elf_file, filename, &elf_head) 2631*0Sstevel@tonic-gate == (GElf_Ehdr *)0) { 2632*0Sstevel@tonic-gate (void) elf_end(elf_file); 2633*0Sstevel@tonic-gate (void) close(fd); 2634*0Sstevel@tonic-gate return; 2635*0Sstevel@tonic-gate } 2636*0Sstevel@tonic-gate if (o_flag) 2637*0Sstevel@tonic-gate dump_exec_header(elf_file, 2638*0Sstevel@tonic-gate (unsigned)elf_head.e_phnum, filename); 2639*0Sstevel@tonic-gate if (x_flag) 2640*0Sstevel@tonic-gate dump_section_table(elf_file, 2641*0Sstevel@tonic-gate &elf_head, filename); 2642*0Sstevel@tonic-gate } else { 2643*0Sstevel@tonic-gate (void) fprintf(stderr, "%s: %s: invalid file type\n", 2644*0Sstevel@tonic-gate prog_name, filename); 2645*0Sstevel@tonic-gate (void) elf_end(elf_file); 2646*0Sstevel@tonic-gate (void) close(fd); 2647*0Sstevel@tonic-gate return; 2648*0Sstevel@tonic-gate } 2649*0Sstevel@tonic-gate } 2650*0Sstevel@tonic-gate (void) elf_end(elf_file); 2651*0Sstevel@tonic-gate (void) close(fd); 2652*0Sstevel@tonic-gate } 2653*0Sstevel@tonic-gate 2654*0Sstevel@tonic-gate /* 2655*0Sstevel@tonic-gate * Sets up flags for command line options given and then 2656*0Sstevel@tonic-gate * calls each_file() to process each file. 2657*0Sstevel@tonic-gate */ 2658*0Sstevel@tonic-gate int 2659*0Sstevel@tonic-gate main(int argc, char *argv[], char *envp[]) 2660*0Sstevel@tonic-gate { 2661*0Sstevel@tonic-gate char *optstr = OPTSTR; /* option string used by getopt() */ 2662*0Sstevel@tonic-gate int optchar; 2663*0Sstevel@tonic-gate 2664*0Sstevel@tonic-gate 2665*0Sstevel@tonic-gate /* 2666*0Sstevel@tonic-gate * Check for a binary that better fits this architecture. 2667*0Sstevel@tonic-gate */ 2668*0Sstevel@tonic-gate conv_check_native(argv, envp); 2669*0Sstevel@tonic-gate 2670*0Sstevel@tonic-gate prog_name = argv[0]; 2671*0Sstevel@tonic-gate 2672*0Sstevel@tonic-gate (void) setlocale(LC_ALL, ""); 2673*0Sstevel@tonic-gate while ((optchar = getopt(argc, argv, optstr)) != -1) { 2674*0Sstevel@tonic-gate switch (optchar) { 2675*0Sstevel@tonic-gate case 'a': 2676*0Sstevel@tonic-gate a_flag = 1; 2677*0Sstevel@tonic-gate x_flag = 1; 2678*0Sstevel@tonic-gate break; 2679*0Sstevel@tonic-gate case 'g': 2680*0Sstevel@tonic-gate g_flag = 1; 2681*0Sstevel@tonic-gate x_flag = 1; 2682*0Sstevel@tonic-gate break; 2683*0Sstevel@tonic-gate case 'v': 2684*0Sstevel@tonic-gate v_flag = 1; 2685*0Sstevel@tonic-gate break; 2686*0Sstevel@tonic-gate case 'p': 2687*0Sstevel@tonic-gate p_flag = 1; 2688*0Sstevel@tonic-gate break; 2689*0Sstevel@tonic-gate case 'f': 2690*0Sstevel@tonic-gate f_flag = 1; 2691*0Sstevel@tonic-gate z_flag = 1; 2692*0Sstevel@tonic-gate break; 2693*0Sstevel@tonic-gate case 'o': 2694*0Sstevel@tonic-gate o_flag = 1; 2695*0Sstevel@tonic-gate z_flag = 1; 2696*0Sstevel@tonic-gate break; 2697*0Sstevel@tonic-gate case 'h': 2698*0Sstevel@tonic-gate h_flag = 1; 2699*0Sstevel@tonic-gate x_flag = 1; 2700*0Sstevel@tonic-gate z_flag = 1; 2701*0Sstevel@tonic-gate break; 2702*0Sstevel@tonic-gate case 's': 2703*0Sstevel@tonic-gate s_flag = 1; 2704*0Sstevel@tonic-gate x_flag = 1; 2705*0Sstevel@tonic-gate z_flag = 1; 2706*0Sstevel@tonic-gate break; 2707*0Sstevel@tonic-gate case 'd': 2708*0Sstevel@tonic-gate d_flag = 1; 2709*0Sstevel@tonic-gate x_flag = 1; 2710*0Sstevel@tonic-gate z_flag = 1; 2711*0Sstevel@tonic-gate set_range(optarg, &d_low, &d_hi); 2712*0Sstevel@tonic-gate break; 2713*0Sstevel@tonic-gate case 'n': 2714*0Sstevel@tonic-gate n_flag++; 2715*0Sstevel@tonic-gate x_flag = 1; 2716*0Sstevel@tonic-gate z_flag = 1; 2717*0Sstevel@tonic-gate name = optarg; 2718*0Sstevel@tonic-gate break; 2719*0Sstevel@tonic-gate case 'r': 2720*0Sstevel@tonic-gate r_flag = 1; 2721*0Sstevel@tonic-gate x_flag = 1; 2722*0Sstevel@tonic-gate z_flag = 1; 2723*0Sstevel@tonic-gate break; 2724*0Sstevel@tonic-gate case 't': 2725*0Sstevel@tonic-gate t_flag = 1; 2726*0Sstevel@tonic-gate x_flag = 1; 2727*0Sstevel@tonic-gate z_flag = 1; 2728*0Sstevel@tonic-gate break; 2729*0Sstevel@tonic-gate case 'C': 2730*0Sstevel@tonic-gate C_flag = 1; 2731*0Sstevel@tonic-gate t_flag = 1; 2732*0Sstevel@tonic-gate x_flag = 1; 2733*0Sstevel@tonic-gate z_flag = 1; 2734*0Sstevel@tonic-gate break; 2735*0Sstevel@tonic-gate case 'T': 2736*0Sstevel@tonic-gate T_flag = 1; 2737*0Sstevel@tonic-gate x_flag = 1; 2738*0Sstevel@tonic-gate z_flag = 1; 2739*0Sstevel@tonic-gate set_range(optarg, &T_low, &T_hi); 2740*0Sstevel@tonic-gate break; 2741*0Sstevel@tonic-gate case 'c': 2742*0Sstevel@tonic-gate c_flag = 1; 2743*0Sstevel@tonic-gate x_flag = 1; 2744*0Sstevel@tonic-gate z_flag = 1; 2745*0Sstevel@tonic-gate break; 2746*0Sstevel@tonic-gate case 'L': 2747*0Sstevel@tonic-gate L_flag = 1; 2748*0Sstevel@tonic-gate x_flag = 1; 2749*0Sstevel@tonic-gate z_flag = 1; 2750*0Sstevel@tonic-gate break; 2751*0Sstevel@tonic-gate case 'V': 2752*0Sstevel@tonic-gate V_flag = 1; 2753*0Sstevel@tonic-gate (void) fprintf(stderr, "dump: %s %s\n", 2754*0Sstevel@tonic-gate (const char *)SGU_PKG, 2755*0Sstevel@tonic-gate (const char *)SGU_REL); 2756*0Sstevel@tonic-gate break; 2757*0Sstevel@tonic-gate case '?': 2758*0Sstevel@tonic-gate errflag += 1; 2759*0Sstevel@tonic-gate break; 2760*0Sstevel@tonic-gate default: 2761*0Sstevel@tonic-gate break; 2762*0Sstevel@tonic-gate } 2763*0Sstevel@tonic-gate } 2764*0Sstevel@tonic-gate 2765*0Sstevel@tonic-gate if (errflag || (optind >= argc) || (!z_flag && !x_flag)) { 2766*0Sstevel@tonic-gate if (!(V_flag && (argc == 2))) { 2767*0Sstevel@tonic-gate usage(); 2768*0Sstevel@tonic-gate exit(269); 2769*0Sstevel@tonic-gate } 2770*0Sstevel@tonic-gate } 2771*0Sstevel@tonic-gate 2772*0Sstevel@tonic-gate while (optind < argc) { 2773*0Sstevel@tonic-gate each_file(argv[optind]); 2774*0Sstevel@tonic-gate optind++; 2775*0Sstevel@tonic-gate } 2776*0Sstevel@tonic-gate return (0); 2777*0Sstevel@tonic-gate } 2778