1*ae115bc7Smrj /* 2*ae115bc7Smrj * CDDL HEADER START 3*ae115bc7Smrj * 4*ae115bc7Smrj * The contents of this file are subject to the terms of the 5*ae115bc7Smrj * Common Development and Distribution License (the "License"). 6*ae115bc7Smrj * You may not use this file except in compliance with the License. 7*ae115bc7Smrj * 8*ae115bc7Smrj * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*ae115bc7Smrj * or http://www.opensolaris.org/os/licensing. 10*ae115bc7Smrj * See the License for the specific language governing permissions 11*ae115bc7Smrj * and limitations under the License. 12*ae115bc7Smrj * 13*ae115bc7Smrj * When distributing Covered Code, include this CDDL HEADER in each 14*ae115bc7Smrj * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*ae115bc7Smrj * If applicable, add the following below this CDDL HEADER, with the 16*ae115bc7Smrj * fields enclosed by brackets "[]" replaced with your own identifying 17*ae115bc7Smrj * information: Portions Copyright [yyyy] [name of copyright owner] 18*ae115bc7Smrj * 19*ae115bc7Smrj * CDDL HEADER END 20*ae115bc7Smrj */ 21*ae115bc7Smrj 22*ae115bc7Smrj /* 23*ae115bc7Smrj * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 24*ae115bc7Smrj * Use is subject to license terms. 25*ae115bc7Smrj */ 26*ae115bc7Smrj 27*ae115bc7Smrj #pragma ident "%Z%%M% %I% %E% SMI" 28*ae115bc7Smrj 29*ae115bc7Smrj #include <stdlib.h> 30*ae115bc7Smrj #include <fcntl.h> 31*ae115bc7Smrj #include <strings.h> 32*ae115bc7Smrj #include <stdio.h> 33*ae115bc7Smrj #include <errno.h> 34*ae115bc7Smrj #include <sys/types.h> 35*ae115bc7Smrj #include <sys/inttypes.h> 36*ae115bc7Smrj #include <sys/elf.h> 37*ae115bc7Smrj #include <sys/elf_notes.h> 38*ae115bc7Smrj #include <sys/mman.h> 39*ae115bc7Smrj #include <sys/stat.h> 40*ae115bc7Smrj #include <sys/statvfs.h> 41*ae115bc7Smrj 42*ae115bc7Smrj static char *pname; 43*ae115bc7Smrj static char *fname; 44*ae115bc7Smrj static char *image; /* pointer to the ELF file in memory */ 45*ae115bc7Smrj 46*ae115bc7Smrj #define ELFSEEK(offset) ((void *)(image + offset)) 47*ae115bc7Smrj 48*ae115bc7Smrj /* 49*ae115bc7Smrj * Extract the PT_LOAD bits and format them into a .s 50*ae115bc7Smrj */ 51*ae115bc7Smrj static void 52*ae115bc7Smrj extract32(Elf32_Ehdr *eh) 53*ae115bc7Smrj { 54*ae115bc7Smrj Elf32_Phdr *phdr; 55*ae115bc7Smrj caddr_t allphdrs; 56*ae115bc7Smrj int i; 57*ae115bc7Smrj int c; 58*ae115bc7Smrj unsigned char *bytes; 59*ae115bc7Smrj uint_t cnt = 10; 60*ae115bc7Smrj 61*ae115bc7Smrj allphdrs = NULL; 62*ae115bc7Smrj 63*ae115bc7Smrj if (eh->e_type != ET_EXEC) { 64*ae115bc7Smrj (void) fprintf(stderr, "%s: not ET_EXEC, e_type = 0x%x\n", 65*ae115bc7Smrj pname, eh->e_type); 66*ae115bc7Smrj exit(1); 67*ae115bc7Smrj } 68*ae115bc7Smrj if (eh->e_phnum == 0 || eh->e_phoff == 0) { 69*ae115bc7Smrj (void) fprintf(stderr, "%s: no program headers\n", pname); 70*ae115bc7Smrj exit(1); 71*ae115bc7Smrj } 72*ae115bc7Smrj 73*ae115bc7Smrj /* 74*ae115bc7Smrj * Get the program headers. 75*ae115bc7Smrj */ 76*ae115bc7Smrj allphdrs = ELFSEEK(eh->e_phoff); 77*ae115bc7Smrj if (allphdrs == NULL) { 78*ae115bc7Smrj (void) fprintf(stderr, "%s: Failed to get %d program hdrs\n", 79*ae115bc7Smrj pname, eh->e_phnum); 80*ae115bc7Smrj exit(1); 81*ae115bc7Smrj } 82*ae115bc7Smrj 83*ae115bc7Smrj /* 84*ae115bc7Smrj * Find the PT_LOAD section 85*ae115bc7Smrj */ 86*ae115bc7Smrj for (i = 0; i < eh->e_phnum; i++) { 87*ae115bc7Smrj /*LINTED [ELF program header alignment]*/ 88*ae115bc7Smrj phdr = (Elf32_Phdr *)(allphdrs + eh->e_phentsize * i); 89*ae115bc7Smrj 90*ae115bc7Smrj if (phdr->p_type != PT_LOAD) 91*ae115bc7Smrj continue; 92*ae115bc7Smrj 93*ae115bc7Smrj if (phdr->p_memsz == 0) 94*ae115bc7Smrj continue; 95*ae115bc7Smrj 96*ae115bc7Smrj bytes = ELFSEEK(phdr->p_offset); 97*ae115bc7Smrj for (c = 0; c < phdr->p_filesz; ++c) { 98*ae115bc7Smrj if (c % cnt == 0) 99*ae115bc7Smrj (void) printf("\n .byte "); 100*ae115bc7Smrj else 101*ae115bc7Smrj (void) printf(","); 102*ae115bc7Smrj (void) printf("0x%x", bytes[c]); 103*ae115bc7Smrj } 104*ae115bc7Smrj for (; c < phdr->p_memsz; ++c) { 105*ae115bc7Smrj if (c % cnt == 0) { 106*ae115bc7Smrj (void) printf("\n .byte "); 107*ae115bc7Smrj cnt = 20; 108*ae115bc7Smrj } else { 109*ae115bc7Smrj (void) printf(", "); 110*ae115bc7Smrj } 111*ae115bc7Smrj (void) printf("0"); 112*ae115bc7Smrj } 113*ae115bc7Smrj (void) printf("\n"); 114*ae115bc7Smrj return; 115*ae115bc7Smrj } 116*ae115bc7Smrj 117*ae115bc7Smrj (void) fprintf(stderr, "%s: Failed finding PT_LOAD section\n", pname); 118*ae115bc7Smrj exit(1); 119*ae115bc7Smrj } 120*ae115bc7Smrj 121*ae115bc7Smrj static void 122*ae115bc7Smrj extract64(Elf64_Ehdr *eh) 123*ae115bc7Smrj { 124*ae115bc7Smrj Elf64_Phdr *phdr; 125*ae115bc7Smrj caddr_t allphdrs; 126*ae115bc7Smrj int i; 127*ae115bc7Smrj int c; 128*ae115bc7Smrj unsigned char *bytes; 129*ae115bc7Smrj uint_t cnt = 10; 130*ae115bc7Smrj 131*ae115bc7Smrj allphdrs = NULL; 132*ae115bc7Smrj 133*ae115bc7Smrj if (eh->e_type != ET_EXEC) { 134*ae115bc7Smrj (void) fprintf(stderr, "%s: not ET_EXEC, e_type = 0x%x\n", 135*ae115bc7Smrj pname, eh->e_type); 136*ae115bc7Smrj exit(1); 137*ae115bc7Smrj } 138*ae115bc7Smrj if (eh->e_phnum == 0 || eh->e_phoff == 0) { 139*ae115bc7Smrj (void) fprintf(stderr, "%s: no program headers\n", pname); 140*ae115bc7Smrj exit(1); 141*ae115bc7Smrj } 142*ae115bc7Smrj 143*ae115bc7Smrj /* 144*ae115bc7Smrj * Get the program headers. 145*ae115bc7Smrj */ 146*ae115bc7Smrj allphdrs = ELFSEEK(eh->e_phoff); 147*ae115bc7Smrj if (allphdrs == NULL) { 148*ae115bc7Smrj (void) fprintf(stderr, "%s: Failed to get %d program hdrs\n", 149*ae115bc7Smrj pname, eh->e_phnum); 150*ae115bc7Smrj exit(1); 151*ae115bc7Smrj } 152*ae115bc7Smrj 153*ae115bc7Smrj /* 154*ae115bc7Smrj * Find the PT_LOAD section 155*ae115bc7Smrj */ 156*ae115bc7Smrj for (i = 0; i < eh->e_phnum; i++) { 157*ae115bc7Smrj /*LINTED [ELF program header alignment]*/ 158*ae115bc7Smrj phdr = (Elf64_Phdr *)(allphdrs + eh->e_phentsize * i); 159*ae115bc7Smrj 160*ae115bc7Smrj if (phdr->p_type != PT_LOAD) 161*ae115bc7Smrj continue; 162*ae115bc7Smrj 163*ae115bc7Smrj if (phdr->p_memsz == 0) 164*ae115bc7Smrj continue; 165*ae115bc7Smrj 166*ae115bc7Smrj bytes = ELFSEEK(phdr->p_offset); 167*ae115bc7Smrj for (c = 0; c < phdr->p_filesz; ++c) { 168*ae115bc7Smrj if (c % cnt == 0) 169*ae115bc7Smrj (void) printf("\n .byte "); 170*ae115bc7Smrj else 171*ae115bc7Smrj (void) printf(","); 172*ae115bc7Smrj (void) printf("0x%x", bytes[c]); 173*ae115bc7Smrj } 174*ae115bc7Smrj for (; c < phdr->p_memsz; ++c) { 175*ae115bc7Smrj if (c % cnt == 0) { 176*ae115bc7Smrj (void) printf("\n .byte "); 177*ae115bc7Smrj cnt = 20; 178*ae115bc7Smrj } else { 179*ae115bc7Smrj (void) printf(", "); 180*ae115bc7Smrj } 181*ae115bc7Smrj (void) printf("0"); 182*ae115bc7Smrj } 183*ae115bc7Smrj (void) printf("\n"); 184*ae115bc7Smrj return; 185*ae115bc7Smrj } 186*ae115bc7Smrj 187*ae115bc7Smrj (void) fprintf(stderr, "%s: Failed finding PT_LOAD section\n", pname); 188*ae115bc7Smrj exit(1); 189*ae115bc7Smrj } 190*ae115bc7Smrj 191*ae115bc7Smrj int 192*ae115bc7Smrj main(int argc, char **argv) 193*ae115bc7Smrj { 194*ae115bc7Smrj int fd; 195*ae115bc7Smrj uchar_t *ident; 196*ae115bc7Smrj void *hdr = NULL; 197*ae115bc7Smrj struct stat stats; 198*ae115bc7Smrj ssize_t r; 199*ae115bc7Smrj uint_t len; 200*ae115bc7Smrj 201*ae115bc7Smrj /* 202*ae115bc7Smrj * we expect one argument -- the elf file 203*ae115bc7Smrj */ 204*ae115bc7Smrj if (argc != 2) { 205*ae115bc7Smrj (void) fprintf(stderr, "usage: %s <unix-elf-file>\n", argv[0]); 206*ae115bc7Smrj exit(1); 207*ae115bc7Smrj } 208*ae115bc7Smrj 209*ae115bc7Smrj pname = strrchr(argv[0], '/'); 210*ae115bc7Smrj if (pname == NULL) 211*ae115bc7Smrj pname = argv[0]; 212*ae115bc7Smrj else 213*ae115bc7Smrj ++pname; 214*ae115bc7Smrj 215*ae115bc7Smrj fname = argv[1]; 216*ae115bc7Smrj fd = open(fname, O_RDONLY); 217*ae115bc7Smrj if (fd < 0) { 218*ae115bc7Smrj (void) fprintf(stderr, "%s: open(%s, O_RDONLY) failed, %s\n", 219*ae115bc7Smrj pname, fname, strerror(errno)); 220*ae115bc7Smrj exit(1); 221*ae115bc7Smrj } 222*ae115bc7Smrj 223*ae115bc7Smrj if (stat(fname, &stats) < 0) { 224*ae115bc7Smrj (void) fprintf(stderr, "%s: stat(%s, ...) failed, %s\n", 225*ae115bc7Smrj pname, fname, strerror(errno)); 226*ae115bc7Smrj exit(1); 227*ae115bc7Smrj } 228*ae115bc7Smrj 229*ae115bc7Smrj len = stats.st_blocks * 512; 230*ae115bc7Smrj len += 0xfff; 231*ae115bc7Smrj len &= ~0xfff; 232*ae115bc7Smrj 233*ae115bc7Smrj #ifdef BUG_6491065_IS_FIXED 234*ae115bc7Smrj /* 235*ae115bc7Smrj * mmap the file 236*ae115bc7Smrj */ 237*ae115bc7Smrj image = mmap(NULL, len, PROT_READ, MAP_SHARED, fd, 0); 238*ae115bc7Smrj if (image == MAP_FAILED) { 239*ae115bc7Smrj (void) fprintf(stderr, "%s: mmap() of %s failed, %s\n", 240*ae115bc7Smrj pname, fname, strerror(errno)); 241*ae115bc7Smrj exit(1); 242*ae115bc7Smrj } 243*ae115bc7Smrj #else 244*ae115bc7Smrj if ((image = malloc(stats.st_size)) == NULL) { 245*ae115bc7Smrj (void) fprintf(stderr, "%s: out of memory\n", pname); 246*ae115bc7Smrj exit(1); 247*ae115bc7Smrj } 248*ae115bc7Smrj if ((r = read(fd, image, stats.st_size)) != stats.st_size) { 249*ae115bc7Smrj (void) fprintf(stderr, "%s: stat(%s, ...) failed, %s\n", 250*ae115bc7Smrj pname, fname, strerror(errno)); 251*ae115bc7Smrj exit(1); 252*ae115bc7Smrj } 253*ae115bc7Smrj #endif 254*ae115bc7Smrj 255*ae115bc7Smrj ident = ELFSEEK(0); 256*ae115bc7Smrj if (ident[EI_MAG0] != ELFMAG0 || ident[EI_MAG1] != ELFMAG1 || 257*ae115bc7Smrj ident[EI_MAG2] != ELFMAG2 || ident[EI_MAG3] != ELFMAG3) { 258*ae115bc7Smrj (void) fprintf(stderr, "%s: not an ELF file!\n", pname); 259*ae115bc7Smrj exit(1); 260*ae115bc7Smrj } 261*ae115bc7Smrj 262*ae115bc7Smrj if (ident[EI_CLASS] == ELFCLASS32) { 263*ae115bc7Smrj hdr = ELFSEEK(0); 264*ae115bc7Smrj extract32(hdr); 265*ae115bc7Smrj } else if (ident[EI_CLASS] == ELFCLASS64) { 266*ae115bc7Smrj hdr = ELFSEEK(0); 267*ae115bc7Smrj extract64(hdr); 268*ae115bc7Smrj } else { 269*ae115bc7Smrj (void) fprintf(stderr, "%s: Wrong ELF class 0x%x\n", pname, 270*ae115bc7Smrj ident[EI_CLASS]); 271*ae115bc7Smrj exit(1); 272*ae115bc7Smrj } 273*ae115bc7Smrj return (0); 274*ae115bc7Smrj } 275