1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright (c) 1988 AT&T 23 * Copyright (c) 1989 AT&T 24 * All Rights Reserved 25 * 26 * 27 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 28 * Use is subject to license terms. 29 */ 30 31 #pragma ident "%Z%%M% %I% %E% SMI" 32 33 /* UNIX HEADERS */ 34 #include <stdio.h> 35 #include <stdlib.h> 36 #include <unistd.h> 37 #include <fcntl.h> 38 #include <libelf.h> 39 40 41 /* SIZE HEADER */ 42 #include "defs.h" 43 44 /* RELEASE STRING */ 45 #include "conv.h" 46 #include "sgs.h" 47 48 49 /* EXTERNAL VARIABLES DEFINED */ 50 int fflag = 0, /* print full output if -f option is supplied */ 51 Fflag = 0, /* print full output if -F option is supplied */ 52 nflag = 0; /* include NOLOAD sections in size if -n */ 53 /* option is supplied */ 54 int numbase = DECIMAL; 55 static int errflag = 0; /* Global error flag */ 56 int oneflag = 0; 57 int exitcode = 0; /* Global exit code */ 58 char *fname; 59 char *archive; 60 int is_archive = 0; 61 62 static char *tool_name; 63 64 static void usagerr(); 65 66 #define OPTSTR "VoxnfF" /* option string for usage error message */ 67 #define GETOPTSTR "VoxnfF?" /* option string for getopt */ 68 69 static Elf *elf; 70 static Elf_Arhdr *arhdr; 71 72 /* 73 * main(argc, argv) 74 * 75 * parses the command line 76 * opens, processes and closes each object file command line argument 77 * 78 * defines: 79 * - int numbase = HEX if the -x flag is in the command line 80 * = OCTAL if the -o flag is in the command line 81 * = DECIMAL if the -d flag is in the command line 82 * 83 * calls: 84 * - process(filename) to print the size information in the object file 85 * filename 86 * 87 * prints: 88 * - an error message if any unknown options appear on the command line 89 * - a usage message if no object file args appear on the command line 90 * - an error message if it can't open an object file 91 * or if the object file has the wrong magic number 92 * 93 * exits 1 - errors found, 0 - no errors 94 */ 95 int 96 main(int argc, char ** argv, char ** envp) 97 { 98 /* UNIX FUNCTIONS CALLED */ 99 extern void error(); 100 101 /* SIZE FUNCTIONS CALLED */ 102 extern void process(); 103 104 /* EXTERNAL VARIABLES USED */ 105 extern int numbase; 106 extern int errflag; 107 extern int oneflag; 108 extern int optind; 109 extern char *fname; 110 111 int c; 112 static int fd; 113 extern char *archive; 114 Elf_Cmd cmd; 115 Elf *arf; 116 unsigned Vflag = 0; 117 118 /* 119 * Check for a binary that better fits this architecture. 120 */ 121 (void) conv_check_native(argv, envp); 122 123 tool_name = argv[0]; 124 125 while ((c = getopt(argc, argv, GETOPTSTR)) != EOF) { 126 switch (c) { 127 case 'o': 128 if (numbase != HEX) 129 numbase = OCTAL; 130 else 131 (void) fprintf(stderr, 132 "size: -x set, -o ignored\n"); 133 break; 134 135 case 'd': 136 numbase = DECIMAL; 137 break; 138 139 case 'x': 140 if (numbase != OCTAL) 141 numbase = HEX; 142 else 143 (void) fprintf(stderr, 144 "size: -o set, -x ignored\n"); 145 break; 146 147 case 'f': 148 fflag++; 149 break; 150 151 case 'F': 152 Fflag++; 153 break; 154 155 case 'n': 156 nflag++; 157 break; 158 case 'V': 159 (void) fprintf(stderr, "size: %s %s\n", 160 (const char *)SGU_PKG, 161 (const char *)SGU_REL); 162 Vflag++; 163 break; 164 case '?': 165 errflag++; 166 break; 167 default: 168 break; 169 } 170 } 171 if (errflag || (optind >= argc)) { 172 if (!(Vflag && (argc == 2) && !errflag)) { 173 usagerr(); 174 } 175 } 176 if ((argc - optind) == 1) { 177 oneflag++; /* only one file to process */ 178 } 179 180 if (elf_version(EV_CURRENT) == EV_NONE) { 181 (void) fprintf(stderr, "size: Libelf is out of date"); 182 exit(FATAL); /* library out of date */ 183 } 184 185 for (; optind < argc; optind++) { 186 fname = argv[optind]; 187 if ((fd = open(argv[optind], O_RDONLY)) == -1) { 188 error(fname, "cannot open"); 189 } else { 190 cmd = ELF_C_READ; 191 arf = 0; 192 193 if ((arf = elf_begin(fd, cmd, arf)) == 0) { 194 /* error(fname, "cannot open"); */ 195 (void) fprintf(stderr, 196 "size: %s: %s\n", fname, elf_errmsg(-1)); 197 return (FATAL); 198 } 199 200 if (elf_kind(arf) == ELF_K_AR) { 201 archive = argv[optind]; 202 } else { 203 archive = ""; 204 } 205 206 while ((elf = elf_begin(fd, cmd, arf)) != 0) { 207 if ((arhdr = elf_getarhdr(elf)) == 0) { 208 if (elf_kind(arf) == ELF_K_NONE) { 209 /* BEGIN CSTYLED */ 210 (void) fprintf(stderr, 211 "%s: %s: invalid file type\n", 212 tool_name, fname); 213 /* END CSTYLED */ 214 exitcode++; 215 break; 216 } else { 217 process(elf); 218 } 219 } else if (arhdr->ar_name[0] != '/') { 220 fname = arhdr->ar_name; 221 if (elf_kind(arf) == ELF_K_NONE) { 222 /* BEGIN CSTYLED */ 223 (void) fprintf(stderr, 224 "%s: %s[%s]: invalid file type\n", 225 tool_name, archive, fname); 226 /* END CSTYLED */ 227 exitcode++; 228 break; 229 } else { 230 is_archive++; 231 process(elf); 232 } 233 } 234 cmd = elf_next(elf); 235 (void) elf_end(elf); 236 } 237 (void) elf_end(arf); 238 (void) close(fd); 239 } 240 } 241 if (exitcode) 242 exit(FATAL); 243 else 244 exit(0); 245 return (0); 246 } 247 248 static void 249 usagerr() 250 { 251 (void) fprintf(stderr, 252 "usage: %s [-%s] file(s)...\n", tool_name, OPTSTR); 253 exitcode++; 254 } 255