10Sstevel@tonic-gate /* 20Sstevel@tonic-gate * CDDL HEADER START 30Sstevel@tonic-gate * 40Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*1976Sab196087 * Common Development and Distribution License (the "License"). 6*1976Sab196087 * You may not use this file except in compliance with the License. 70Sstevel@tonic-gate * 80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 100Sstevel@tonic-gate * See the License for the specific language governing permissions 110Sstevel@tonic-gate * and limitations under the License. 120Sstevel@tonic-gate * 130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 180Sstevel@tonic-gate * 190Sstevel@tonic-gate * CDDL HEADER END 200Sstevel@tonic-gate */ 210Sstevel@tonic-gate /* Copyright (c) 1988 AT&T */ 220Sstevel@tonic-gate /* All Rights Reserved */ 230Sstevel@tonic-gate 240Sstevel@tonic-gate 250Sstevel@tonic-gate /* 26*1976Sab196087 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 27*1976Sab196087 * Use is subject to license terms. 280Sstevel@tonic-gate */ 290Sstevel@tonic-gate 300Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 310Sstevel@tonic-gate 320Sstevel@tonic-gate #include <stdio.h> 330Sstevel@tonic-gate #include <stdlib.h> 340Sstevel@tonic-gate #include <unistd.h> 350Sstevel@tonic-gate #include <string.h> 360Sstevel@tonic-gate #include <libelf.h> 370Sstevel@tonic-gate #include <limits.h> 380Sstevel@tonic-gate #include "dump.h" 390Sstevel@tonic-gate 400Sstevel@tonic-gate extern int p_flag; 41*1976Sab196087 extern char *prog_name; 420Sstevel@tonic-gate 430Sstevel@tonic-gate 440Sstevel@tonic-gate /* 450Sstevel@tonic-gate * Print the symbols in the archive symbol table. 460Sstevel@tonic-gate */ 470Sstevel@tonic-gate void 48*1976Sab196087 ar_sym_read(Elf *elf, char *filename) 490Sstevel@tonic-gate { 500Sstevel@tonic-gate Elf_Arsym * arsym; 510Sstevel@tonic-gate size_t cnt, ptr; 520Sstevel@tonic-gate 530Sstevel@tonic-gate if ((arsym = elf_getarsym(elf, &ptr)) == NULL) { 540Sstevel@tonic-gate (void) fprintf(stderr, "%s: %s: no archive symbol table\n", 550Sstevel@tonic-gate prog_name, filename); 560Sstevel@tonic-gate return; 570Sstevel@tonic-gate } 580Sstevel@tonic-gate 590Sstevel@tonic-gate (void) printf("%s:\n", filename); 600Sstevel@tonic-gate 610Sstevel@tonic-gate if (!p_flag) { 620Sstevel@tonic-gate (void) printf(" **** ARCHIVE SYMBOL TABLE ****\n"); 630Sstevel@tonic-gate (void) printf("%-8s %s\n\n", "Offset", "Name"); 640Sstevel@tonic-gate } 650Sstevel@tonic-gate for (cnt = 0; cnt < ptr; cnt++, arsym++) { 660Sstevel@tonic-gate if (arsym->as_off) { 670Sstevel@tonic-gate /* LINTED */ 680Sstevel@tonic-gate (void) printf("%-8.8x %s\n", (int)arsym->as_off, 690Sstevel@tonic-gate (arsym->as_name ? arsym->as_name : "")); 700Sstevel@tonic-gate } 710Sstevel@tonic-gate } 720Sstevel@tonic-gate } 730Sstevel@tonic-gate 740Sstevel@tonic-gate /* 750Sstevel@tonic-gate * Print the program execution header. Input is an opened ELF object file, the 760Sstevel@tonic-gate * number of structure instances in the header as recorded in the ELF header, 770Sstevel@tonic-gate * and the filename. 780Sstevel@tonic-gate */ 790Sstevel@tonic-gate void 800Sstevel@tonic-gate dump_exec_header(Elf *elf_file, unsigned nseg, char *filename) 810Sstevel@tonic-gate { 820Sstevel@tonic-gate GElf_Ehdr ehdr; 830Sstevel@tonic-gate GElf_Phdr p_phdr; 840Sstevel@tonic-gate int counter; 850Sstevel@tonic-gate int field; 860Sstevel@tonic-gate extern int v_flag, p_flag; 870Sstevel@tonic-gate extern char *prog_name; 880Sstevel@tonic-gate 890Sstevel@tonic-gate if (gelf_getclass(elf_file) == ELFCLASS64) 900Sstevel@tonic-gate field = 16; 910Sstevel@tonic-gate else 920Sstevel@tonic-gate field = 12; 930Sstevel@tonic-gate 940Sstevel@tonic-gate if (!p_flag) { 950Sstevel@tonic-gate (void) printf(" ***** PROGRAM EXECUTION HEADER *****\n"); 960Sstevel@tonic-gate (void) printf("%-*s%-*s%-*s%s\n", 970Sstevel@tonic-gate field, "Type", field, "Offset", 980Sstevel@tonic-gate field, "Vaddr", "Paddr"); 990Sstevel@tonic-gate (void) printf("%-*s%-*s%-*s%s\n\n", 1000Sstevel@tonic-gate field, "Filesz", field, "Memsz", 1010Sstevel@tonic-gate field, "Flags", "Align"); 1020Sstevel@tonic-gate } 1030Sstevel@tonic-gate 1040Sstevel@tonic-gate if ((gelf_getehdr(elf_file, &ehdr) == 0) || (ehdr.e_phnum == 0)) { 1050Sstevel@tonic-gate return; 1060Sstevel@tonic-gate } 1070Sstevel@tonic-gate 1080Sstevel@tonic-gate for (counter = 0; counter < nseg; counter++) { 1090Sstevel@tonic-gate 1100Sstevel@tonic-gate if (gelf_getphdr(elf_file, counter, &p_phdr) == 0) { 1110Sstevel@tonic-gate (void) fprintf(stderr, 1120Sstevel@tonic-gate "%s: %s: premature EOF on program exec header\n", 1130Sstevel@tonic-gate prog_name, filename); 1140Sstevel@tonic-gate return; 1150Sstevel@tonic-gate } 1160Sstevel@tonic-gate 1170Sstevel@tonic-gate if (!v_flag) { 1180Sstevel@tonic-gate (void) printf( 1190Sstevel@tonic-gate "%-*d%-#*llx%-#*llx%-#*llx\n%-#*llx%-#*llx%-*u%-#*llx\n\n", 1200Sstevel@tonic-gate field, EC_WORD(p_phdr.p_type), 1210Sstevel@tonic-gate field, EC_OFF(p_phdr.p_offset), 1220Sstevel@tonic-gate field, EC_ADDR(p_phdr.p_vaddr), 1230Sstevel@tonic-gate field, EC_ADDR(p_phdr.p_paddr), 1240Sstevel@tonic-gate field, EC_XWORD(p_phdr.p_filesz), 1250Sstevel@tonic-gate field, EC_XWORD(p_phdr.p_memsz), 1260Sstevel@tonic-gate field, EC_WORD(p_phdr.p_flags), 1270Sstevel@tonic-gate field, EC_XWORD(p_phdr.p_align)); 1280Sstevel@tonic-gate } else { 1290Sstevel@tonic-gate switch (p_phdr.p_type) { 1300Sstevel@tonic-gate case PT_NULL: 1310Sstevel@tonic-gate (void) printf("%-*s", field, "NULL"); 1320Sstevel@tonic-gate break; 1330Sstevel@tonic-gate case PT_LOAD: 1340Sstevel@tonic-gate (void) printf("%-*s", field, "LOAD"); 1350Sstevel@tonic-gate break; 1360Sstevel@tonic-gate case PT_DYNAMIC: 1370Sstevel@tonic-gate (void) printf("%-*s", field, "DYN"); 1380Sstevel@tonic-gate break; 1390Sstevel@tonic-gate case PT_INTERP: 1400Sstevel@tonic-gate (void) printf("%-*s", field, "INTERP"); 1410Sstevel@tonic-gate break; 1420Sstevel@tonic-gate case PT_NOTE: 1430Sstevel@tonic-gate (void) printf("%-*s", field, "NOTE"); 1440Sstevel@tonic-gate break; 1450Sstevel@tonic-gate case PT_SHLIB: 1460Sstevel@tonic-gate (void) printf("%-*s", field, "SHLIB"); 1470Sstevel@tonic-gate break; 1480Sstevel@tonic-gate case PT_PHDR: 1490Sstevel@tonic-gate (void) printf("%-*s", field, "PHDR"); 1500Sstevel@tonic-gate break; 1510Sstevel@tonic-gate case PT_TLS: 1520Sstevel@tonic-gate (void) printf("%-*s", field, "TLS"); 1530Sstevel@tonic-gate break; 1540Sstevel@tonic-gate case PT_SUNWBSS: 1550Sstevel@tonic-gate (void) printf("%-*s", field, "SUNWBSS"); 1560Sstevel@tonic-gate break; 1570Sstevel@tonic-gate case PT_SUNWSTACK: 1580Sstevel@tonic-gate (void) printf("%-*s", field, "SUNWSTACK"); 1590Sstevel@tonic-gate break; 1600Sstevel@tonic-gate default: 1610Sstevel@tonic-gate (void) printf("%-*d", field, 1620Sstevel@tonic-gate (int)p_phdr.p_type); 1630Sstevel@tonic-gate break; 1640Sstevel@tonic-gate } 1650Sstevel@tonic-gate (void) printf( 1660Sstevel@tonic-gate "%-#*llx%-#*llx%-#*llx\n%-#*llx%-#*llx", 1670Sstevel@tonic-gate field, EC_OFF(p_phdr.p_offset), 1680Sstevel@tonic-gate field, EC_ADDR(p_phdr.p_vaddr), 1690Sstevel@tonic-gate field, EC_ADDR(p_phdr.p_paddr), 1700Sstevel@tonic-gate field, EC_XWORD(p_phdr.p_filesz), 1710Sstevel@tonic-gate field, EC_XWORD(p_phdr.p_memsz)); 1720Sstevel@tonic-gate 1730Sstevel@tonic-gate switch (p_phdr.p_flags) { 1740Sstevel@tonic-gate case 0: (void) printf("%-*s", field, "---"); break; 1750Sstevel@tonic-gate case PF_X: 1760Sstevel@tonic-gate (void) printf("%-*s", field, "--x"); 1770Sstevel@tonic-gate break; 1780Sstevel@tonic-gate case PF_W: 1790Sstevel@tonic-gate (void) printf("%-*s", field, "-w-"); 1800Sstevel@tonic-gate break; 1810Sstevel@tonic-gate case PF_W+PF_X: 1820Sstevel@tonic-gate (void) printf("%-*s", field, "-wx"); 1830Sstevel@tonic-gate break; 1840Sstevel@tonic-gate case PF_R: 1850Sstevel@tonic-gate (void) printf("%-*s", field, "r--"); 1860Sstevel@tonic-gate break; 1870Sstevel@tonic-gate case PF_R+PF_X: 1880Sstevel@tonic-gate (void) printf("%-*s", field, "r-x"); 1890Sstevel@tonic-gate break; 1900Sstevel@tonic-gate case PF_R+PF_W: 1910Sstevel@tonic-gate (void) printf("%-*s", field, "rw-"); 1920Sstevel@tonic-gate break; 1930Sstevel@tonic-gate case PF_R+PF_W+PF_X: 1940Sstevel@tonic-gate (void) printf("%-*s", field, "rwx"); 1950Sstevel@tonic-gate break; 1960Sstevel@tonic-gate default: 1970Sstevel@tonic-gate (void) printf("%-*d", field, p_phdr.p_flags); 1980Sstevel@tonic-gate break; 1990Sstevel@tonic-gate } 2000Sstevel@tonic-gate (void) printf( 2010Sstevel@tonic-gate "%-#*llx\n\n", field, EC_XWORD(p_phdr.p_align)); 2020Sstevel@tonic-gate } 2030Sstevel@tonic-gate } 2040Sstevel@tonic-gate } 205