xref: /onnv-gate/usr/src/cmd/sgs/mcs/common/main.c (revision 0:68f95e015346)
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  *	Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
28*0Sstevel@tonic-gate  *	Use is subject to license terms.
29*0Sstevel@tonic-gate  */
30*0Sstevel@tonic-gate 
31*0Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
32*0Sstevel@tonic-gate 
33*0Sstevel@tonic-gate #include "stdlib.h"
34*0Sstevel@tonic-gate #include "conv.h"
35*0Sstevel@tonic-gate #include "mcs.h"
36*0Sstevel@tonic-gate #include "extern.h"
37*0Sstevel@tonic-gate #define	OPTUNIT	100
38*0Sstevel@tonic-gate 
39*0Sstevel@tonic-gate static size_t optcnt = 0;
40*0Sstevel@tonic-gate static size_t optbufsz = OPTUNIT;
41*0Sstevel@tonic-gate 
42*0Sstevel@tonic-gate /*
43*0Sstevel@tonic-gate  * Function prototypes.
44*0Sstevel@tonic-gate  */
45*0Sstevel@tonic-gate static void usage(int);
46*0Sstevel@tonic-gate static void sigexit(int);
47*0Sstevel@tonic-gate static int setup_sectname(char *, int);
48*0Sstevel@tonic-gate static void check_swap();
49*0Sstevel@tonic-gate static void queue(int, char *);
50*0Sstevel@tonic-gate 
51*0Sstevel@tonic-gate int
52*0Sstevel@tonic-gate main(int argc, char ** argv, char ** envp)
53*0Sstevel@tonic-gate {
54*0Sstevel@tonic-gate 	const char	*opt;
55*0Sstevel@tonic-gate 	char		*str;
56*0Sstevel@tonic-gate 	int		error_count = 0, num_sect = 0, errflag = 0, Dflag = 0;
57*0Sstevel@tonic-gate 	int		c, i, my_prog;
58*0Sstevel@tonic-gate 	Cmd_Info	*cmd_info;
59*0Sstevel@tonic-gate 
60*0Sstevel@tonic-gate 	/*
61*0Sstevel@tonic-gate 	 * Check for a binary that better fits this architecture.
62*0Sstevel@tonic-gate 	 */
63*0Sstevel@tonic-gate 	conv_check_native(argv, envp);
64*0Sstevel@tonic-gate 
65*0Sstevel@tonic-gate 	/*
66*0Sstevel@tonic-gate 	 * mcs(1) and strip() are hard linked together, determine which command
67*0Sstevel@tonic-gate 	 * was invoked.
68*0Sstevel@tonic-gate 	 */
69*0Sstevel@tonic-gate 	prog = argv[0];
70*0Sstevel@tonic-gate 	if ((str = strrchr(prog, '/')) != NULL)
71*0Sstevel@tonic-gate 		str++;
72*0Sstevel@tonic-gate 	else
73*0Sstevel@tonic-gate 		str = prog;
74*0Sstevel@tonic-gate 
75*0Sstevel@tonic-gate 	if (strcmp(str, "mcs") == 0) {
76*0Sstevel@tonic-gate 		my_prog = MCS;
77*0Sstevel@tonic-gate 		opt = "Da:cdn:pVz?";
78*0Sstevel@tonic-gate 	} else if (strcmp(str, "strip") == 0) {
79*0Sstevel@tonic-gate 		my_prog = STRIP;
80*0Sstevel@tonic-gate 		opt = "DlxV?";
81*0Sstevel@tonic-gate 	} else
82*0Sstevel@tonic-gate 		exit(1);
83*0Sstevel@tonic-gate 
84*0Sstevel@tonic-gate 	(void) setlocale(LC_ALL, "");
85*0Sstevel@tonic-gate #if !defined(TEXT_DOMAIN)
86*0Sstevel@tonic-gate #define	TEXT_DOMAIN "SYS_TEST"
87*0Sstevel@tonic-gate #endif
88*0Sstevel@tonic-gate 	(void) textdomain(TEXT_DOMAIN);
89*0Sstevel@tonic-gate 
90*0Sstevel@tonic-gate 	for (i = 0; signum[i]; i++)
91*0Sstevel@tonic-gate 		if (signal(signum[i], SIG_IGN) != SIG_IGN)
92*0Sstevel@tonic-gate 			(void) signal(signum[i], sigexit);
93*0Sstevel@tonic-gate 
94*0Sstevel@tonic-gate 	if ((Action =
95*0Sstevel@tonic-gate 	    malloc(optbufsz * sizeof (struct action))) == NULL) {
96*0Sstevel@tonic-gate 		error_message(MALLOC_ERROR, PLAIN_ERROR, (char *)0, prog);
97*0Sstevel@tonic-gate 		exit(FAILURE);
98*0Sstevel@tonic-gate 	}
99*0Sstevel@tonic-gate 
100*0Sstevel@tonic-gate 	/*
101*0Sstevel@tonic-gate 	 * Allocate command info structure
102*0Sstevel@tonic-gate 	 */
103*0Sstevel@tonic-gate 	cmd_info = (Cmd_Info *) calloc(1, sizeof (Cmd_Info));
104*0Sstevel@tonic-gate 	if (cmd_info == NULL) {
105*0Sstevel@tonic-gate 		error_message(MALLOC_ERROR, PLAIN_ERROR, (char *)0, prog);
106*0Sstevel@tonic-gate 		exit(FAILURE);
107*0Sstevel@tonic-gate 	}
108*0Sstevel@tonic-gate 	if (my_prog == STRIP)
109*0Sstevel@tonic-gate 		cmd_info->flags |= I_AM_STRIP;
110*0Sstevel@tonic-gate 
111*0Sstevel@tonic-gate 	while ((c = getopt(argc, argv, (char *)opt)) != EOF) {
112*0Sstevel@tonic-gate 		switch (c) {
113*0Sstevel@tonic-gate 		case 'D':
114*0Sstevel@tonic-gate 			optcnt++;
115*0Sstevel@tonic-gate 			Dflag++;
116*0Sstevel@tonic-gate 			break;
117*0Sstevel@tonic-gate 		case 'a':
118*0Sstevel@tonic-gate 			optcnt++;
119*0Sstevel@tonic-gate 			queue(ACT_APPEND, optarg);
120*0Sstevel@tonic-gate 			cmd_info->flags |= (MIGHT_CHG | aFLAG);
121*0Sstevel@tonic-gate 			cmd_info->str_size += strlen(optarg) + 1;
122*0Sstevel@tonic-gate 			break;
123*0Sstevel@tonic-gate 		case 'c':
124*0Sstevel@tonic-gate 			optcnt++;
125*0Sstevel@tonic-gate 			queue(ACT_COMPRESS, NULL);
126*0Sstevel@tonic-gate 			cmd_info->flags |= (MIGHT_CHG | cFLAG);
127*0Sstevel@tonic-gate 			break;
128*0Sstevel@tonic-gate 		case 'd':
129*0Sstevel@tonic-gate 			optcnt++;
130*0Sstevel@tonic-gate 			if (CHK_OPT(cmd_info, dFLAG) == 0)
131*0Sstevel@tonic-gate 				queue(ACT_DELETE, NULL);
132*0Sstevel@tonic-gate 			cmd_info->flags |= (MIGHT_CHG | dFLAG);
133*0Sstevel@tonic-gate 			break;
134*0Sstevel@tonic-gate 		case 'z':
135*0Sstevel@tonic-gate 			optcnt++;
136*0Sstevel@tonic-gate 			queue(ACT_ZAP, NULL);
137*0Sstevel@tonic-gate 			cmd_info->flags |= (MIGHT_CHG | zFLAG);
138*0Sstevel@tonic-gate 			break;
139*0Sstevel@tonic-gate 		case 'n':
140*0Sstevel@tonic-gate 			(void) setup_sectname(optarg, my_prog);
141*0Sstevel@tonic-gate 			num_sect++;
142*0Sstevel@tonic-gate 			break;
143*0Sstevel@tonic-gate 		case 'l':
144*0Sstevel@tonic-gate 			optcnt++;
145*0Sstevel@tonic-gate 			cmd_info->flags |= lFLAG;
146*0Sstevel@tonic-gate 			break;
147*0Sstevel@tonic-gate 		case 'p':
148*0Sstevel@tonic-gate 			optcnt++;
149*0Sstevel@tonic-gate 			queue(ACT_PRINT, NULL);
150*0Sstevel@tonic-gate 			cmd_info->flags |= pFLAG;
151*0Sstevel@tonic-gate 			break;
152*0Sstevel@tonic-gate 		case 'x':
153*0Sstevel@tonic-gate 			optcnt++;
154*0Sstevel@tonic-gate 			cmd_info->flags |= xFLAG;
155*0Sstevel@tonic-gate 			break;
156*0Sstevel@tonic-gate 		case 'V':
157*0Sstevel@tonic-gate 			cmd_info->flags |= VFLAG;
158*0Sstevel@tonic-gate 			(void) fprintf(stderr, "%s: %s %s\n", prog,
159*0Sstevel@tonic-gate 			    (const char *)SGU_PKG, (const char *)SGU_REL);
160*0Sstevel@tonic-gate 			break;
161*0Sstevel@tonic-gate 		case '?':
162*0Sstevel@tonic-gate 			errflag++;
163*0Sstevel@tonic-gate 			break;
164*0Sstevel@tonic-gate 		default:
165*0Sstevel@tonic-gate 			break;
166*0Sstevel@tonic-gate 		}
167*0Sstevel@tonic-gate 	}
168*0Sstevel@tonic-gate 
169*0Sstevel@tonic-gate 	if (errflag) {
170*0Sstevel@tonic-gate 		usage(my_prog);
171*0Sstevel@tonic-gate 		exit(FAILURE);
172*0Sstevel@tonic-gate 	}
173*0Sstevel@tonic-gate 
174*0Sstevel@tonic-gate 	if (Dflag)
175*0Sstevel@tonic-gate 		check_swap();
176*0Sstevel@tonic-gate 
177*0Sstevel@tonic-gate 	/*
178*0Sstevel@tonic-gate 	 * strip command may not take any options.
179*0Sstevel@tonic-gate 	 */
180*0Sstevel@tonic-gate 	if (my_prog != STRIP) {
181*0Sstevel@tonic-gate 		if (argc == optind &&
182*0Sstevel@tonic-gate 		    (CHK_OPT(cmd_info, MIGHT_CHG) || CHK_OPT(cmd_info, pFLAG) ||
183*0Sstevel@tonic-gate 		    argc == 1))
184*0Sstevel@tonic-gate 			usage(my_prog);
185*0Sstevel@tonic-gate 		else if (!CHK_OPT(cmd_info, MIGHT_CHG) &&
186*0Sstevel@tonic-gate 		    !CHK_OPT(cmd_info, pFLAG) && !CHK_OPT(cmd_info, VFLAG))
187*0Sstevel@tonic-gate 			usage(my_prog);
188*0Sstevel@tonic-gate 	}
189*0Sstevel@tonic-gate 
190*0Sstevel@tonic-gate 	/*
191*0Sstevel@tonic-gate 	 * This version only allows multiple section names
192*0Sstevel@tonic-gate 	 * only for -d option.
193*0Sstevel@tonic-gate 	 */
194*0Sstevel@tonic-gate 	if ((num_sect >= 2) && (CHK_OPT(cmd_info, pFLAG) ||
195*0Sstevel@tonic-gate 	    CHK_OPT(cmd_info, aFLAG) ||
196*0Sstevel@tonic-gate 	    CHK_OPT(cmd_info, cFLAG))) {
197*0Sstevel@tonic-gate 		error_message(USAGE_ERROR, PLAIN_ERROR, (char *)0,  prog);
198*0Sstevel@tonic-gate 		exit(1);
199*0Sstevel@tonic-gate 	}
200*0Sstevel@tonic-gate 
201*0Sstevel@tonic-gate 	/*
202*0Sstevel@tonic-gate 	 * If no -n was specified,
203*0Sstevel@tonic-gate 	 * set the default, ".comment".
204*0Sstevel@tonic-gate 	 * This is for mcs only.
205*0Sstevel@tonic-gate 	 */
206*0Sstevel@tonic-gate 	if (num_sect == 0 && my_prog == MCS) {
207*0Sstevel@tonic-gate 		(void) setup_sectname(".comment", MCS);
208*0Sstevel@tonic-gate 	}
209*0Sstevel@tonic-gate 
210*0Sstevel@tonic-gate 	/*
211*0Sstevel@tonic-gate 	 * If I am strip command, then add needed
212*0Sstevel@tonic-gate 	 * section names.
213*0Sstevel@tonic-gate 	 */
214*0Sstevel@tonic-gate 	if (my_prog == STRIP) {
215*0Sstevel@tonic-gate 		(void) setup_sectname(".line", MCS);
216*0Sstevel@tonic-gate 		if (CHK_OPT(cmd_info, lFLAG) == 0) {
217*0Sstevel@tonic-gate 			(void) setup_sectname(".debug", STRIP);
218*0Sstevel@tonic-gate 			(void) setup_sectname(".stab", STRIP);
219*0Sstevel@tonic-gate 		}
220*0Sstevel@tonic-gate 		if (CHK_OPT(cmd_info, dFLAG) == 0) {
221*0Sstevel@tonic-gate 			queue(ACT_DELETE, NULL);
222*0Sstevel@tonic-gate 			cmd_info->flags |= MIGHT_CHG;
223*0Sstevel@tonic-gate 			cmd_info->flags |= dFLAG;
224*0Sstevel@tonic-gate 		}
225*0Sstevel@tonic-gate 	}
226*0Sstevel@tonic-gate 
227*0Sstevel@tonic-gate 	(void) elf_version(EV_NONE);
228*0Sstevel@tonic-gate 	if (elf_version(EV_CURRENT) == EV_NONE) {
229*0Sstevel@tonic-gate 		error_message(ELFVER_ERROR, LIBelf_ERROR, elf_errmsg(-1), prog);
230*0Sstevel@tonic-gate 		exit(FAILURE);
231*0Sstevel@tonic-gate 	}
232*0Sstevel@tonic-gate 
233*0Sstevel@tonic-gate 	if (CHK_OPT(cmd_info, pFLAG) || CHK_OPT(cmd_info, MIGHT_CHG)) {
234*0Sstevel@tonic-gate 		for (; optind < argc; optind++) {
235*0Sstevel@tonic-gate 			error_count = error_count +
236*0Sstevel@tonic-gate 			    (each_file(argv[optind], cmd_info));
237*0Sstevel@tonic-gate 		}
238*0Sstevel@tonic-gate 	}
239*0Sstevel@tonic-gate 
240*0Sstevel@tonic-gate 	if (Dflag)
241*0Sstevel@tonic-gate 		check_swap();
242*0Sstevel@tonic-gate 	mcs_exit(error_count);
243*0Sstevel@tonic-gate 	/*NOTREACHED*/
244*0Sstevel@tonic-gate 	return (0);
245*0Sstevel@tonic-gate }
246*0Sstevel@tonic-gate 
247*0Sstevel@tonic-gate /*
248*0Sstevel@tonic-gate  * Supplementary functions
249*0Sstevel@tonic-gate  */
250*0Sstevel@tonic-gate static void
251*0Sstevel@tonic-gate queue(int activity, char *string)
252*0Sstevel@tonic-gate {
253*0Sstevel@tonic-gate 	if (optcnt > optbufsz) {
254*0Sstevel@tonic-gate 		optbufsz = optbufsz * 2;
255*0Sstevel@tonic-gate 		if ((Action = realloc((struct action *)Action,
256*0Sstevel@tonic-gate 		    optbufsz * sizeof (struct action))) == NULL) {
257*0Sstevel@tonic-gate 		    error_message(MALLOC_ERROR, PLAIN_ERROR, (char *)0, prog);
258*0Sstevel@tonic-gate 		    mcs_exit(FAILURE);
259*0Sstevel@tonic-gate 		}
260*0Sstevel@tonic-gate 	}
261*0Sstevel@tonic-gate 	Action[actmax].a_action = activity;
262*0Sstevel@tonic-gate 	Action[actmax].a_cnt = 0;
263*0Sstevel@tonic-gate 	Action[actmax].a_string = string;
264*0Sstevel@tonic-gate 	actmax++;
265*0Sstevel@tonic-gate }
266*0Sstevel@tonic-gate 
267*0Sstevel@tonic-gate /*ARGSUSED0*/
268*0Sstevel@tonic-gate static void
269*0Sstevel@tonic-gate sigexit(int i)
270*0Sstevel@tonic-gate {
271*0Sstevel@tonic-gate 	(void) unlink(artmpfile);
272*0Sstevel@tonic-gate 	(void) unlink(elftmpfile);
273*0Sstevel@tonic-gate 	exit(100);
274*0Sstevel@tonic-gate }
275*0Sstevel@tonic-gate 
276*0Sstevel@tonic-gate static void
277*0Sstevel@tonic-gate usage(int me)
278*0Sstevel@tonic-gate {
279*0Sstevel@tonic-gate 	if (me == MCS)
280*0Sstevel@tonic-gate 		(void) fprintf(stderr, gettext(
281*0Sstevel@tonic-gate 		"usage: %s [-cdpVz] [-a string] [-n name] file ...\n"), prog);
282*0Sstevel@tonic-gate 	else
283*0Sstevel@tonic-gate 		(void) fprintf(stderr, gettext(
284*0Sstevel@tonic-gate 		"usage: %s [-lVx] file ...\n"), prog);
285*0Sstevel@tonic-gate 	mcs_exit(FAILURE);
286*0Sstevel@tonic-gate }
287*0Sstevel@tonic-gate 
288*0Sstevel@tonic-gate void
289*0Sstevel@tonic-gate mcs_exit(int val)
290*0Sstevel@tonic-gate {
291*0Sstevel@tonic-gate 	(void) unlink(artmpfile);
292*0Sstevel@tonic-gate 	(void) unlink(elftmpfile);
293*0Sstevel@tonic-gate 	exit(val);
294*0Sstevel@tonic-gate }
295*0Sstevel@tonic-gate 
296*0Sstevel@tonic-gate /*
297*0Sstevel@tonic-gate  * Insert the section name 'name' into the
298*0Sstevel@tonic-gate  * section list.
299*0Sstevel@tonic-gate  */
300*0Sstevel@tonic-gate static int
301*0Sstevel@tonic-gate setup_sectname(char *name, int whoami)
302*0Sstevel@tonic-gate {
303*0Sstevel@tonic-gate 	S_Name *new;
304*0Sstevel@tonic-gate 
305*0Sstevel@tonic-gate 	/*
306*0Sstevel@tonic-gate 	 * Check if the name is already specified or not.
307*0Sstevel@tonic-gate 	 */
308*0Sstevel@tonic-gate 	if ((whoami == MCS) && (sectcmp(name) == 0))
309*0Sstevel@tonic-gate 		return (0);
310*0Sstevel@tonic-gate 
311*0Sstevel@tonic-gate 	/*
312*0Sstevel@tonic-gate 	 * Allocate one
313*0Sstevel@tonic-gate 	 */
314*0Sstevel@tonic-gate 	if ((new = malloc(sizeof (S_Name))) == NULL) {
315*0Sstevel@tonic-gate 		error_message(MALLOC_ERROR, PLAIN_ERROR, (char *)0, prog);
316*0Sstevel@tonic-gate 		exit(FAILURE);
317*0Sstevel@tonic-gate 	}
318*0Sstevel@tonic-gate 	new->name = strdup(name);
319*0Sstevel@tonic-gate 	if (new->name == NULL) {
320*0Sstevel@tonic-gate 		error_message(USAGE_ERROR, PLAIN_ERROR, (char *)0, prog);
321*0Sstevel@tonic-gate 		exit(FAILURE);
322*0Sstevel@tonic-gate 	}
323*0Sstevel@tonic-gate 	if (whoami == STRIP)
324*0Sstevel@tonic-gate 		new->flags = SNAME_FLG_STRNCMP;
325*0Sstevel@tonic-gate 	new->next = NULL;
326*0Sstevel@tonic-gate 
327*0Sstevel@tonic-gate 	/*
328*0Sstevel@tonic-gate 	 * Put this one in the list
329*0Sstevel@tonic-gate 	 */
330*0Sstevel@tonic-gate 	new->next = sect_head;
331*0Sstevel@tonic-gate 	sect_head = new;
332*0Sstevel@tonic-gate 
333*0Sstevel@tonic-gate 	return (0);
334*0Sstevel@tonic-gate }
335*0Sstevel@tonic-gate 
336*0Sstevel@tonic-gate /*
337*0Sstevel@tonic-gate  * Check if the 'name' exists in the section list.
338*0Sstevel@tonic-gate  *
339*0Sstevel@tonic-gate  * If found
340*0Sstevel@tonic-gate  *	return 0;
341*0Sstevel@tonic-gate  * else
342*0Sstevel@tonic-gate  *	return 1
343*0Sstevel@tonic-gate  */
344*0Sstevel@tonic-gate int
345*0Sstevel@tonic-gate sectcmp(char *name)
346*0Sstevel@tonic-gate {
347*0Sstevel@tonic-gate 	/*
348*0Sstevel@tonic-gate 	 * Check if the name is already specified or not.
349*0Sstevel@tonic-gate 	 */
350*0Sstevel@tonic-gate 	if (sect_head != NULL) {
351*0Sstevel@tonic-gate 		S_Name *p1 = sect_head;
352*0Sstevel@tonic-gate 		while (p1 != NULL) {
353*0Sstevel@tonic-gate 			if (p1->flags & SNAME_FLG_STRNCMP) {
354*0Sstevel@tonic-gate 				if (strncmp(p1->name,
355*0Sstevel@tonic-gate 				    name, strlen(p1->name)) == 0)
356*0Sstevel@tonic-gate 					return (0);
357*0Sstevel@tonic-gate 			} else if (strcmp(p1->name, name) == 0) {
358*0Sstevel@tonic-gate 				return (0);	/* silently ignore */
359*0Sstevel@tonic-gate 			}
360*0Sstevel@tonic-gate 			p1 = p1->next;
361*0Sstevel@tonic-gate 		}
362*0Sstevel@tonic-gate 	}
363*0Sstevel@tonic-gate 	return (1);
364*0Sstevel@tonic-gate }
365*0Sstevel@tonic-gate 
366*0Sstevel@tonic-gate static void
367*0Sstevel@tonic-gate check_swap()
368*0Sstevel@tonic-gate {
369*0Sstevel@tonic-gate 	(void) system("/usr/sbin/swap -s");
370*0Sstevel@tonic-gate }
371