mandoc: update to 1.14.5
[unleashed.git] / bin / size / main.c
blobc5b0b4d015200cea33bf2be140b9b3f95bfd1ee4
1 /*
2 * CDDL HEADER START
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.
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.
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]
19 * CDDL HEADER END
22 * Copyright (c) 1988 AT&T
23 * Copyright (c) 1989 AT&T
24 * All Rights Reserved
27 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
28 * Use is subject to license terms.
31 /* UNIX HEADERS */
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <unistd.h>
35 #include <fcntl.h>
36 #include <libelf.h>
39 /* SIZE HEADER */
40 #include "defs.h"
42 /* RELEASE STRING */
43 #include <sgs.h>
46 /* EXTERNAL VARIABLES DEFINED */
47 int fflag = 0, /* print full output if -f option is supplied */
48 Fflag = 0, /* print full output if -F option is supplied */
49 nflag = 0; /* include NOLOAD sections in size if -n */
50 /* option is supplied */
51 int numbase = DECIMAL;
52 static int errflag = 0; /* Global error flag */
53 int oneflag = 0;
54 int exitcode = 0; /* Global exit code */
55 char *fname;
56 char *archive;
57 int is_archive = 0;
59 static char *tool_name;
61 static void usagerr();
63 #define OPTSTR "VoxnfF" /* option string for usage error message */
64 #define GETOPTSTR "VoxnfF?" /* option string for getopt */
66 static Elf *elf;
67 static Elf_Arhdr *arhdr;
70 * main(argc, argv)
72 * parses the command line
73 * opens, processes and closes each object file command line argument
75 * defines:
76 * - int numbase = HEX if the -x flag is in the command line
77 * = OCTAL if the -o flag is in the command line
78 * = DECIMAL if the -d flag is in the command line
80 * calls:
81 * - process(filename) to print the size information in the object file
82 * filename
84 * prints:
85 * - an error message if any unknown options appear on the command line
86 * - a usage message if no object file args appear on the command line
87 * - an error message if it can't open an object file
88 * or if the object file has the wrong magic number
90 * exits 1 - errors found, 0 - no errors
92 int
93 main(int argc, char ** argv, char ** envp)
95 /* UNIX FUNCTIONS CALLED */
96 extern void error();
98 /* SIZE FUNCTIONS CALLED */
99 extern void process();
101 /* EXTERNAL VARIABLES USED */
102 extern int numbase;
103 extern int errflag;
104 extern int oneflag;
105 extern int optind;
106 extern char *fname;
108 int c;
109 static int fd;
110 extern char *archive;
111 Elf_Cmd cmd;
112 Elf *arf;
113 unsigned Vflag = 0;
115 tool_name = argv[0];
117 while ((c = getopt(argc, argv, GETOPTSTR)) != EOF) {
118 switch (c) {
119 case 'o':
120 if (numbase != HEX)
121 numbase = OCTAL;
122 else
123 (void) fprintf(stderr,
124 "size: -x set, -o ignored\n");
125 break;
127 case 'd':
128 numbase = DECIMAL;
129 break;
131 case 'x':
132 if (numbase != OCTAL)
133 numbase = HEX;
134 else
135 (void) fprintf(stderr,
136 "size: -o set, -x ignored\n");
137 break;
139 case 'f':
140 fflag++;
141 break;
143 case 'F':
144 Fflag++;
145 break;
147 case 'n':
148 nflag++;
149 break;
150 case 'V':
151 (void) fprintf(stderr, "size: %s %s\n",
152 (const char *)SGU_PKG,
153 (const char *)SGU_REL);
154 Vflag++;
155 break;
156 case '?':
157 errflag++;
158 break;
159 default:
160 break;
163 if (errflag || (optind >= argc)) {
164 if (!(Vflag && (argc == 2) && !errflag)) {
165 usagerr();
168 if ((argc - optind) == 1) {
169 oneflag++; /* only one file to process */
172 if (elf_version(EV_CURRENT) == EV_NONE) {
173 (void) fprintf(stderr, "size: Libelf is out of date");
174 exit(FATAL); /* library out of date */
177 for (; optind < argc; optind++) {
178 fname = argv[optind];
179 if ((fd = open(argv[optind], O_RDONLY)) == -1) {
180 error(fname, "cannot open");
181 } else {
182 cmd = ELF_C_READ;
183 arf = 0;
185 if ((arf = elf_begin(fd, cmd, arf)) == 0) {
186 /* error(fname, "cannot open"); */
187 (void) fprintf(stderr,
188 "size: %s: %s\n", fname, elf_errmsg(-1));
189 return (FATAL);
192 if (elf_kind(arf) == ELF_K_AR) {
193 archive = argv[optind];
194 } else {
195 archive = "";
198 while ((elf = elf_begin(fd, cmd, arf)) != 0) {
199 if ((arhdr = elf_getarhdr(elf)) == 0) {
200 if (elf_kind(arf) == ELF_K_NONE) {
201 /* BEGIN CSTYLED */
202 (void) fprintf(stderr,
203 "%s: %s: invalid file type\n",
204 tool_name, fname);
205 /* END CSTYLED */
206 exitcode++;
207 break;
208 } else {
209 process(elf);
211 } else if (arhdr->ar_name[0] != '/') {
212 fname = arhdr->ar_name;
213 if (elf_kind(arf) == ELF_K_NONE) {
214 /* BEGIN CSTYLED */
215 (void) fprintf(stderr,
216 "%s: %s[%s]: invalid file type\n",
217 tool_name, archive, fname);
218 /* END CSTYLED */
219 exitcode++;
220 break;
221 } else {
222 is_archive++;
223 process(elf);
226 cmd = elf_next(elf);
227 (void) elf_end(elf);
229 (void) elf_end(arf);
230 (void) close(fd);
233 if (exitcode)
234 exit(FATAL);
235 else
236 exit(0);
237 return (0);
240 static void
241 usagerr()
243 (void) fprintf(stderr,
244 "usage: %s [-%s] file(s)...\n", tool_name, OPTSTR);
245 exitcode++;