xref: /titanic_51/usr/src/cmd/sysdef/sysdef.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate  *
4*7c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate  * with the License.
8*7c478bd9Sstevel@tonic-gate  *
9*7c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate  * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate  *
14*7c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate  *
20*7c478bd9Sstevel@tonic-gate  * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate  */
22*7c478bd9Sstevel@tonic-gate /*
23*7c478bd9Sstevel@tonic-gate  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
24*7c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
25*7c478bd9Sstevel@tonic-gate  */
26*7c478bd9Sstevel@tonic-gate 
27*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
28*7c478bd9Sstevel@tonic-gate 
29*7c478bd9Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
30*7c478bd9Sstevel@tonic-gate /*	  All Rights Reserved  	*/
31*7c478bd9Sstevel@tonic-gate 
32*7c478bd9Sstevel@tonic-gate 	/*
33*7c478bd9Sstevel@tonic-gate 	 * This command can now print the value of data items
34*7c478bd9Sstevel@tonic-gate 	 * from [1] /dev/kmem is the default, and [2] a named
35*7c478bd9Sstevel@tonic-gate 	 * file passed with the -n argument.  If the read is from
36*7c478bd9Sstevel@tonic-gate 	 * /dev/kmem, we also print the value of BSS symbols.
37*7c478bd9Sstevel@tonic-gate 	 * The logic to support this is: if read is from file,
38*7c478bd9Sstevel@tonic-gate 	 * [1] find the section number of .bss, [2] look through
39*7c478bd9Sstevel@tonic-gate 	 * nlist for symbols that are in .bss section and zero
40*7c478bd9Sstevel@tonic-gate 	 * the n_value field.  At print time, if the n_value field
41*7c478bd9Sstevel@tonic-gate 	 * is non-zero, print the info.
42*7c478bd9Sstevel@tonic-gate 	 *
43*7c478bd9Sstevel@tonic-gate 	 * This protects us from trying to read a bss symbol from
44*7c478bd9Sstevel@tonic-gate 	 * the file and, possibly, dropping core.
45*7c478bd9Sstevel@tonic-gate 	 *
46*7c478bd9Sstevel@tonic-gate 	 * When reading from /dev/kmem, the n_value field is the
47*7c478bd9Sstevel@tonic-gate 	 * seek address, and the contents are read from that address.
48*7c478bd9Sstevel@tonic-gate 	 *
49*7c478bd9Sstevel@tonic-gate 	 * NOTE: when reading from /dev/kmem, the actual, incore
50*7c478bd9Sstevel@tonic-gate 	 * values will be printed, for example: the current nodename
51*7c478bd9Sstevel@tonic-gate 	 * will be printed, etc.
52*7c478bd9Sstevel@tonic-gate 	 *
53*7c478bd9Sstevel@tonic-gate 	 * the cmn line usage is: sysdef -i -n namelist -h -d -D
54*7c478bd9Sstevel@tonic-gate 	 * (-i for incore, though this is now the default, the option
55*7c478bd9Sstevel@tonic-gate 	 * is left in place for SVID compatibility)
56*7c478bd9Sstevel@tonic-gate 	 */
57*7c478bd9Sstevel@tonic-gate #include	<stdio.h>
58*7c478bd9Sstevel@tonic-gate #include	<nlist.h>
59*7c478bd9Sstevel@tonic-gate #include	<string.h>
60*7c478bd9Sstevel@tonic-gate #include	<sys/types.h>
61*7c478bd9Sstevel@tonic-gate #include	<sys/sysmacros.h>
62*7c478bd9Sstevel@tonic-gate #include	<sys/var.h>
63*7c478bd9Sstevel@tonic-gate #include	<sys/tuneable.h>
64*7c478bd9Sstevel@tonic-gate #include	<sys/modctl.h>
65*7c478bd9Sstevel@tonic-gate #include	<sys/fcntl.h>
66*7c478bd9Sstevel@tonic-gate #include	<sys/utsname.h>
67*7c478bd9Sstevel@tonic-gate #include	<sys/resource.h>
68*7c478bd9Sstevel@tonic-gate #include	<sys/conf.h>
69*7c478bd9Sstevel@tonic-gate #include	<sys/stat.h>
70*7c478bd9Sstevel@tonic-gate #include	<sys/signal.h>
71*7c478bd9Sstevel@tonic-gate #include	<sys/priocntl.h>
72*7c478bd9Sstevel@tonic-gate #include	<sys/procset.h>
73*7c478bd9Sstevel@tonic-gate #include	<sys/systeminfo.h>
74*7c478bd9Sstevel@tonic-gate #include	<sys/machelf.h>
75*7c478bd9Sstevel@tonic-gate #include	<dirent.h>
76*7c478bd9Sstevel@tonic-gate #include	<ctype.h>
77*7c478bd9Sstevel@tonic-gate #include	<stdlib.h>
78*7c478bd9Sstevel@tonic-gate #include	<time.h>
79*7c478bd9Sstevel@tonic-gate #include	<unistd.h>
80*7c478bd9Sstevel@tonic-gate #include	<fcntl.h>
81*7c478bd9Sstevel@tonic-gate 
82*7c478bd9Sstevel@tonic-gate #include	<libelf.h>
83*7c478bd9Sstevel@tonic-gate 
84*7c478bd9Sstevel@tonic-gate extern void sysdef_devinfo(void);
85*7c478bd9Sstevel@tonic-gate 
86*7c478bd9Sstevel@tonic-gate static gid_t egid;
87*7c478bd9Sstevel@tonic-gate 
88*7c478bd9Sstevel@tonic-gate #define	SYM_VALUE(sym)	(nl[(sym)].n_value)
89*7c478bd9Sstevel@tonic-gate #define	MEMSEEK(sym)	memseek(sym)
90*7c478bd9Sstevel@tonic-gate #define	MEMREAD(var)	fread((char *)&var, sizeof (var), 1, \
91*7c478bd9Sstevel@tonic-gate 				(incore ? memfile : sysfile))
92*7c478bd9Sstevel@tonic-gate 
93*7c478bd9Sstevel@tonic-gate struct	var	v;
94*7c478bd9Sstevel@tonic-gate struct  tune	tune;
95*7c478bd9Sstevel@tonic-gate 
96*7c478bd9Sstevel@tonic-gate int incore = 1;		/* The default is "incore" */
97*7c478bd9Sstevel@tonic-gate int bss;		/* if read from file, don't read bss symbols */
98*7c478bd9Sstevel@tonic-gate int hostidf = 0;	/* 0 == print hostid with other info, */
99*7c478bd9Sstevel@tonic-gate 			/* 1 == print just the hostid */
100*7c478bd9Sstevel@tonic-gate int devflag = 0;	/* SunOS4.x devinfo compatible output */
101*7c478bd9Sstevel@tonic-gate int drvname_flag = 0;	/* print the driver name as well as the node */
102*7c478bd9Sstevel@tonic-gate int nflag = 0;
103*7c478bd9Sstevel@tonic-gate char	*os = "/dev/ksyms";	/* Wont always have a /kernel/unix */
104*7c478bd9Sstevel@tonic-gate 				/* This wont fully replace it funtionally */
105*7c478bd9Sstevel@tonic-gate 				/* but is a reasonable default/placeholder */
106*7c478bd9Sstevel@tonic-gate 
107*7c478bd9Sstevel@tonic-gate char	*mem = "/dev/kmem";
108*7c478bd9Sstevel@tonic-gate 
109*7c478bd9Sstevel@tonic-gate int	nstrpush;
110*7c478bd9Sstevel@tonic-gate ssize_t	strmsgsz, strctlsz;
111*7c478bd9Sstevel@tonic-gate short	ts_maxupri;
112*7c478bd9Sstevel@tonic-gate char 	sys_name[10];
113*7c478bd9Sstevel@tonic-gate int	nlsize, lnsize;
114*7c478bd9Sstevel@tonic-gate FILE	*sysfile, *memfile;
115*7c478bd9Sstevel@tonic-gate 
116*7c478bd9Sstevel@tonic-gate void	setln(char *, int, int, int);
117*7c478bd9Sstevel@tonic-gate void	getnlist(void);
118*7c478bd9Sstevel@tonic-gate void	memseek(int);
119*7c478bd9Sstevel@tonic-gate void	devices(void);
120*7c478bd9Sstevel@tonic-gate void	sysdev(void);
121*7c478bd9Sstevel@tonic-gate int	setup(char *);
122*7c478bd9Sstevel@tonic-gate void	modules(void);
123*7c478bd9Sstevel@tonic-gate 
124*7c478bd9Sstevel@tonic-gate struct nlist	*nl, *nlptr;
125*7c478bd9Sstevel@tonic-gate int vs, tu, utsnm, bdev, pnstrpush,
126*7c478bd9Sstevel@tonic-gate     pstrmsgsz, pstrctlsz, endnm,
127*7c478bd9Sstevel@tonic-gate     pts_maxupri, psys_name, fd_cur, fd_max;
128*7c478bd9Sstevel@tonic-gate 
129*7c478bd9Sstevel@tonic-gate #define	MAXI	300
130*7c478bd9Sstevel@tonic-gate #define	MAXL	MAXI/11+10
131*7c478bd9Sstevel@tonic-gate #define	EXPAND	99
132*7c478bd9Sstevel@tonic-gate 
133*7c478bd9Sstevel@tonic-gate struct	link {
134*7c478bd9Sstevel@tonic-gate 	char	*l_cfnm;	/* config name from master table */
135*7c478bd9Sstevel@tonic-gate 	int l_funcidx;		/* index into name list structure */
136*7c478bd9Sstevel@tonic-gate 	unsigned int l_soft :1;	/* software driver flag from master table */
137*7c478bd9Sstevel@tonic-gate 	unsigned int l_dtype:1;	/* set if block device */
138*7c478bd9Sstevel@tonic-gate 	unsigned int l_used :1;	/* set when device entry is printed */
139*7c478bd9Sstevel@tonic-gate } *ln, *lnptr, *majsrch();
140*7c478bd9Sstevel@tonic-gate 
141*7c478bd9Sstevel@tonic-gate 	/* ELF Items */
142*7c478bd9Sstevel@tonic-gate Elf *elfd = NULL;
143*7c478bd9Sstevel@tonic-gate Ehdr *ehdr = NULL;
144*7c478bd9Sstevel@tonic-gate 
145*7c478bd9Sstevel@tonic-gate #ifdef _ELF64
146*7c478bd9Sstevel@tonic-gate #define	elf_getehdr elf64_getehdr
147*7c478bd9Sstevel@tonic-gate #define	elf_getshdr elf64_getshdr
148*7c478bd9Sstevel@tonic-gate #else
149*7c478bd9Sstevel@tonic-gate #define	elf_getehdr elf32_getehdr
150*7c478bd9Sstevel@tonic-gate #define	elf_getshdr elf32_getshdr
151*7c478bd9Sstevel@tonic-gate #endif
152*7c478bd9Sstevel@tonic-gate 
153*7c478bd9Sstevel@tonic-gate /* This procedure checks if module "name" is currently loaded */
154*7c478bd9Sstevel@tonic-gate 
155*7c478bd9Sstevel@tonic-gate int
156*7c478bd9Sstevel@tonic-gate loaded_mod(const char *name)
157*7c478bd9Sstevel@tonic-gate {
158*7c478bd9Sstevel@tonic-gate 	struct modinfo modinfo;
159*7c478bd9Sstevel@tonic-gate 
160*7c478bd9Sstevel@tonic-gate 	/* mi_nextid of -1 means we're getting info on all modules */
161*7c478bd9Sstevel@tonic-gate 	modinfo.mi_id = modinfo.mi_nextid = -1;
162*7c478bd9Sstevel@tonic-gate 	modinfo.mi_info = MI_INFO_ALL;
163*7c478bd9Sstevel@tonic-gate 
164*7c478bd9Sstevel@tonic-gate 	while (modctl(MODINFO, modinfo.mi_id, &modinfo) >= 0)
165*7c478bd9Sstevel@tonic-gate 		if (strcmp(modinfo.mi_name, name) == 0)
166*7c478bd9Sstevel@tonic-gate 			return (1);
167*7c478bd9Sstevel@tonic-gate 
168*7c478bd9Sstevel@tonic-gate 	return (0);
169*7c478bd9Sstevel@tonic-gate }
170*7c478bd9Sstevel@tonic-gate 
171*7c478bd9Sstevel@tonic-gate const char *sysv_transition =
172*7c478bd9Sstevel@tonic-gate 	"*\n* IPC %s\n*\n"
173*7c478bd9Sstevel@tonic-gate 	"* The IPC %s module no longer has system-wide limits.\n"
174*7c478bd9Sstevel@tonic-gate 	"* Please see the \"Solaris Tunable Parameters Reference Manual\" for\n"
175*7c478bd9Sstevel@tonic-gate 	"* information on how the old limits map to resource controls and\n"
176*7c478bd9Sstevel@tonic-gate 	"* the prctl(1) and getrctl(2) manual pages for information on\n"
177*7c478bd9Sstevel@tonic-gate 	"* observing the new limits.\n*\n";
178*7c478bd9Sstevel@tonic-gate 
179*7c478bd9Sstevel@tonic-gate const char *sysv_notloaded =
180*7c478bd9Sstevel@tonic-gate 	"*\n* IPC %s module is not loaded\n*\n";
181*7c478bd9Sstevel@tonic-gate 
182*7c478bd9Sstevel@tonic-gate /*
183*7c478bd9Sstevel@tonic-gate  * Emit a message pointing script writers to the new source for
184*7c478bd9Sstevel@tonic-gate  * System V IPC information.
185*7c478bd9Sstevel@tonic-gate  */
186*7c478bd9Sstevel@tonic-gate void
187*7c478bd9Sstevel@tonic-gate sysvipc(const char *module, const char *name)
188*7c478bd9Sstevel@tonic-gate {
189*7c478bd9Sstevel@tonic-gate 	if (loaded_mod(module))
190*7c478bd9Sstevel@tonic-gate 		(void) printf(sysv_transition, name, name);
191*7c478bd9Sstevel@tonic-gate 	else
192*7c478bd9Sstevel@tonic-gate 		(void) printf(sysv_notloaded, name);
193*7c478bd9Sstevel@tonic-gate }
194*7c478bd9Sstevel@tonic-gate 
195*7c478bd9Sstevel@tonic-gate int
196*7c478bd9Sstevel@tonic-gate main(int argc, char *argv[])
197*7c478bd9Sstevel@tonic-gate {
198*7c478bd9Sstevel@tonic-gate 	struct	utsname utsname;
199*7c478bd9Sstevel@tonic-gate 	Elf_Scn *scn;
200*7c478bd9Sstevel@tonic-gate 	Shdr *shdr;
201*7c478bd9Sstevel@tonic-gate 	char *name;
202*7c478bd9Sstevel@tonic-gate 	int ndx;
203*7c478bd9Sstevel@tonic-gate 	int i;
204*7c478bd9Sstevel@tonic-gate 	char hostid[256], *end;
205*7c478bd9Sstevel@tonic-gate 	unsigned long hostval;
206*7c478bd9Sstevel@tonic-gate 	uint_t	rlim_fd_cur, rlim_fd_max;
207*7c478bd9Sstevel@tonic-gate 
208*7c478bd9Sstevel@tonic-gate 	egid = getegid();
209*7c478bd9Sstevel@tonic-gate 	setegid(getgid());
210*7c478bd9Sstevel@tonic-gate 
211*7c478bd9Sstevel@tonic-gate 	while ((i = getopt(argc, argv, "dihDn:?")) != EOF) {
212*7c478bd9Sstevel@tonic-gate 		switch (i) {
213*7c478bd9Sstevel@tonic-gate 		case 'D':
214*7c478bd9Sstevel@tonic-gate 			drvname_flag++;
215*7c478bd9Sstevel@tonic-gate 			break;
216*7c478bd9Sstevel@tonic-gate 		case 'd':
217*7c478bd9Sstevel@tonic-gate 			devflag++;
218*7c478bd9Sstevel@tonic-gate 			break;
219*7c478bd9Sstevel@tonic-gate 		case 'h':
220*7c478bd9Sstevel@tonic-gate 			hostidf++;
221*7c478bd9Sstevel@tonic-gate 			break;
222*7c478bd9Sstevel@tonic-gate 		case 'i':
223*7c478bd9Sstevel@tonic-gate 			incore++;	/* In case "-i and -n" passed */
224*7c478bd9Sstevel@tonic-gate 			break;		/* Not logical, but not disallowed */
225*7c478bd9Sstevel@tonic-gate 		case 'n':
226*7c478bd9Sstevel@tonic-gate 			nflag = 1;
227*7c478bd9Sstevel@tonic-gate 			incore--;	/* Not incore, use specified file */
228*7c478bd9Sstevel@tonic-gate 			os = optarg;
229*7c478bd9Sstevel@tonic-gate 			break;
230*7c478bd9Sstevel@tonic-gate 		default:
231*7c478bd9Sstevel@tonic-gate 			fprintf(stderr,
232*7c478bd9Sstevel@tonic-gate 				"usage: %s [-D -d -i -h -n namelist]\n",
233*7c478bd9Sstevel@tonic-gate 					argv[0]);
234*7c478bd9Sstevel@tonic-gate 			return (1);
235*7c478bd9Sstevel@tonic-gate 		}
236*7c478bd9Sstevel@tonic-gate 	}
237*7c478bd9Sstevel@tonic-gate 
238*7c478bd9Sstevel@tonic-gate 	/*
239*7c478bd9Sstevel@tonic-gate 	 * Prints hostid of machine.
240*7c478bd9Sstevel@tonic-gate 	 */
241*7c478bd9Sstevel@tonic-gate 	if (sysinfo(SI_HW_SERIAL, hostid, sizeof (hostid)) == -1) {
242*7c478bd9Sstevel@tonic-gate 		fprintf(stderr, "hostid: sysinfo failed\n");
243*7c478bd9Sstevel@tonic-gate 		return (1);
244*7c478bd9Sstevel@tonic-gate 	}
245*7c478bd9Sstevel@tonic-gate 	hostval = strtoul(hostid, &end, 10);
246*7c478bd9Sstevel@tonic-gate 	if (hostval == 0 && end == hostid) {
247*7c478bd9Sstevel@tonic-gate 		fprintf(stderr, "hostid: hostid string returned by "
248*7c478bd9Sstevel@tonic-gate 		    "sysinfo not numeric: \"%s\"\n", hostid);
249*7c478bd9Sstevel@tonic-gate 		return (1);
250*7c478bd9Sstevel@tonic-gate 	}
251*7c478bd9Sstevel@tonic-gate 	if (!devflag)
252*7c478bd9Sstevel@tonic-gate 		fprintf(stdout, "*\n* Hostid\n*\n  %8.8x\n", hostval);
253*7c478bd9Sstevel@tonic-gate 
254*7c478bd9Sstevel@tonic-gate 	if (hostidf)
255*7c478bd9Sstevel@tonic-gate 		return (0);
256*7c478bd9Sstevel@tonic-gate 
257*7c478bd9Sstevel@tonic-gate 	if (((sysfile = fopen(os, "r")) == NULL) && nflag) {
258*7c478bd9Sstevel@tonic-gate 		fprintf(stderr, "cannot open %s\n", os);
259*7c478bd9Sstevel@tonic-gate 		return (1);
260*7c478bd9Sstevel@tonic-gate 	}
261*7c478bd9Sstevel@tonic-gate 
262*7c478bd9Sstevel@tonic-gate 	if (sysfile) {
263*7c478bd9Sstevel@tonic-gate 		if (incore) {
264*7c478bd9Sstevel@tonic-gate 			int memfd;
265*7c478bd9Sstevel@tonic-gate 
266*7c478bd9Sstevel@tonic-gate 			setegid(egid);
267*7c478bd9Sstevel@tonic-gate 			if ((memfile = fopen(mem, "r")) == NULL) {
268*7c478bd9Sstevel@tonic-gate 				fprintf(stderr, "cannot open %s\n", mem);
269*7c478bd9Sstevel@tonic-gate 				return (1);
270*7c478bd9Sstevel@tonic-gate 			}
271*7c478bd9Sstevel@tonic-gate 			setegid(getgid());
272*7c478bd9Sstevel@tonic-gate 
273*7c478bd9Sstevel@tonic-gate 			memfd = fileno(memfile);
274*7c478bd9Sstevel@tonic-gate 			fcntl(memfd, F_SETFD,
275*7c478bd9Sstevel@tonic-gate 			    fcntl(memfd, F_GETFD, 0) | FD_CLOEXEC);
276*7c478bd9Sstevel@tonic-gate 		}
277*7c478bd9Sstevel@tonic-gate 
278*7c478bd9Sstevel@tonic-gate 		/*
279*7c478bd9Sstevel@tonic-gate 		 *	Use libelf to read both COFF and ELF namelists
280*7c478bd9Sstevel@tonic-gate 		 */
281*7c478bd9Sstevel@tonic-gate 
282*7c478bd9Sstevel@tonic-gate 		if ((elf_version(EV_CURRENT)) == EV_NONE) {
283*7c478bd9Sstevel@tonic-gate 			fprintf(stderr, "ELF Access Library out of date\n");
284*7c478bd9Sstevel@tonic-gate 			return (1);
285*7c478bd9Sstevel@tonic-gate 		}
286*7c478bd9Sstevel@tonic-gate 
287*7c478bd9Sstevel@tonic-gate 		if ((elfd = elf_begin(fileno(sysfile), ELF_C_READ,
288*7c478bd9Sstevel@tonic-gate 		    NULL)) == NULL) {
289*7c478bd9Sstevel@tonic-gate 			fprintf(stderr, "Unable to elf begin %s (%s)\n",
290*7c478bd9Sstevel@tonic-gate 				os, elf_errmsg(-1));
291*7c478bd9Sstevel@tonic-gate 			return (1);
292*7c478bd9Sstevel@tonic-gate 		}
293*7c478bd9Sstevel@tonic-gate 
294*7c478bd9Sstevel@tonic-gate 		if ((ehdr = elf_getehdr(elfd)) == NULL) {
295*7c478bd9Sstevel@tonic-gate 			fprintf(stderr, "%s: Can't read Exec header (%s)\n",
296*7c478bd9Sstevel@tonic-gate 				os, elf_errmsg(-1));
297*7c478bd9Sstevel@tonic-gate 			return (1);
298*7c478bd9Sstevel@tonic-gate 		}
299*7c478bd9Sstevel@tonic-gate 
300*7c478bd9Sstevel@tonic-gate 		if ((((elf_kind(elfd)) != ELF_K_ELF) &&
301*7c478bd9Sstevel@tonic-gate 		    ((elf_kind(elfd)) != ELF_K_COFF)) ||
302*7c478bd9Sstevel@tonic-gate 		    (ehdr->e_type != ET_EXEC)) {
303*7c478bd9Sstevel@tonic-gate 			fprintf(stderr, "%s: invalid file\n", os);
304*7c478bd9Sstevel@tonic-gate 			elf_end(elfd);
305*7c478bd9Sstevel@tonic-gate 			return (1);
306*7c478bd9Sstevel@tonic-gate 		}
307*7c478bd9Sstevel@tonic-gate 
308*7c478bd9Sstevel@tonic-gate 		/*
309*7c478bd9Sstevel@tonic-gate 		 *	If this is a file read, look for .bss section
310*7c478bd9Sstevel@tonic-gate 		 */
311*7c478bd9Sstevel@tonic-gate 
312*7c478bd9Sstevel@tonic-gate 		if (!incore) {
313*7c478bd9Sstevel@tonic-gate 			ndx = 1;
314*7c478bd9Sstevel@tonic-gate 			scn = NULL;
315*7c478bd9Sstevel@tonic-gate 			while ((scn = elf_nextscn(elfd, scn)) != NULL) {
316*7c478bd9Sstevel@tonic-gate 				if ((shdr = elf_getshdr(scn)) == NULL) {
317*7c478bd9Sstevel@tonic-gate 					fprintf(stderr,
318*7c478bd9Sstevel@tonic-gate 					    "%s: Error reading Shdr (%s)\n",
319*7c478bd9Sstevel@tonic-gate 					    os, elf_errmsg(-1));
320*7c478bd9Sstevel@tonic-gate 					return (1);
321*7c478bd9Sstevel@tonic-gate 				}
322*7c478bd9Sstevel@tonic-gate 				name = elf_strptr(elfd, ehdr->e_shstrndx,
323*7c478bd9Sstevel@tonic-gate 				    (size_t)shdr->sh_name);
324*7c478bd9Sstevel@tonic-gate 				if ((name) && ((strcmp(name, ".bss")) == 0)) {
325*7c478bd9Sstevel@tonic-gate 					bss = ndx;
326*7c478bd9Sstevel@tonic-gate 				}
327*7c478bd9Sstevel@tonic-gate 				ndx++;
328*7c478bd9Sstevel@tonic-gate 			}
329*7c478bd9Sstevel@tonic-gate 		} /* (!incore) */
330*7c478bd9Sstevel@tonic-gate 	}
331*7c478bd9Sstevel@tonic-gate 
332*7c478bd9Sstevel@tonic-gate 	uname(&utsname);
333*7c478bd9Sstevel@tonic-gate 	if (!devflag)
334*7c478bd9Sstevel@tonic-gate 		printf("*\n* %s Configuration\n*\n", utsname.machine);
335*7c478bd9Sstevel@tonic-gate 
336*7c478bd9Sstevel@tonic-gate 	if (sysfile) {
337*7c478bd9Sstevel@tonic-gate 		nlsize = MAXI;
338*7c478bd9Sstevel@tonic-gate 		lnsize = MAXL;
339*7c478bd9Sstevel@tonic-gate 		nl = (struct nlist *)calloc(nlsize, sizeof (struct nlist));
340*7c478bd9Sstevel@tonic-gate 		ln = (struct link *)calloc(lnsize, sizeof (struct link));
341*7c478bd9Sstevel@tonic-gate 		nlptr = nl;
342*7c478bd9Sstevel@tonic-gate 		lnptr = ln;
343*7c478bd9Sstevel@tonic-gate 
344*7c478bd9Sstevel@tonic-gate 		bdev = setup("bdevsw");
345*7c478bd9Sstevel@tonic-gate 		setup("");
346*7c478bd9Sstevel@tonic-gate 
347*7c478bd9Sstevel@tonic-gate 		getnlist();
348*7c478bd9Sstevel@tonic-gate 
349*7c478bd9Sstevel@tonic-gate 		if (!devflag)
350*7c478bd9Sstevel@tonic-gate 			printf("*\n* Devices\n*\n");
351*7c478bd9Sstevel@tonic-gate 		devices();
352*7c478bd9Sstevel@tonic-gate 		if (devflag)
353*7c478bd9Sstevel@tonic-gate 			return (0);
354*7c478bd9Sstevel@tonic-gate 
355*7c478bd9Sstevel@tonic-gate 		printf("*\n* Loadable Objects\n");
356*7c478bd9Sstevel@tonic-gate 
357*7c478bd9Sstevel@tonic-gate 		modules();
358*7c478bd9Sstevel@tonic-gate 	}
359*7c478bd9Sstevel@tonic-gate 
360*7c478bd9Sstevel@tonic-gate 	printf("*\n* System Configuration\n*\n");
361*7c478bd9Sstevel@tonic-gate 
362*7c478bd9Sstevel@tonic-gate 	sysdev();
363*7c478bd9Sstevel@tonic-gate 
364*7c478bd9Sstevel@tonic-gate 	if (sysfile) {
365*7c478bd9Sstevel@tonic-gate 		/* easy stuff */
366*7c478bd9Sstevel@tonic-gate 		printf("*\n* Tunable Parameters\n*\n");
367*7c478bd9Sstevel@tonic-gate 		nlptr = nl;
368*7c478bd9Sstevel@tonic-gate 		vs = setup("v");
369*7c478bd9Sstevel@tonic-gate 		tu = setup("tune");
370*7c478bd9Sstevel@tonic-gate 		utsnm = setup("utsname");
371*7c478bd9Sstevel@tonic-gate 		pnstrpush = setup("nstrpush");
372*7c478bd9Sstevel@tonic-gate 		pstrmsgsz = setup("strmsgsz");
373*7c478bd9Sstevel@tonic-gate 		pstrctlsz = setup("strctlsz");
374*7c478bd9Sstevel@tonic-gate 		pts_maxupri = setup("ts_maxupri");
375*7c478bd9Sstevel@tonic-gate 		psys_name = setup("sys_name");
376*7c478bd9Sstevel@tonic-gate 		fd_cur = setup("rlim_fd_cur");
377*7c478bd9Sstevel@tonic-gate 		fd_max = setup("rlim_fd_max");
378*7c478bd9Sstevel@tonic-gate 
379*7c478bd9Sstevel@tonic-gate 		/*
380*7c478bd9Sstevel@tonic-gate 		 * This assignment to endnm must follow all calls to setup().
381*7c478bd9Sstevel@tonic-gate 		 */
382*7c478bd9Sstevel@tonic-gate 		endnm = setup("");
383*7c478bd9Sstevel@tonic-gate 
384*7c478bd9Sstevel@tonic-gate 		getnlist();
385*7c478bd9Sstevel@tonic-gate 
386*7c478bd9Sstevel@tonic-gate 		for (nlptr = &nl[vs]; nlptr != &nl[endnm]; nlptr++) {
387*7c478bd9Sstevel@tonic-gate 			if (nlptr->n_value == 0 &&
388*7c478bd9Sstevel@tonic-gate 			    (incore || nlptr->n_scnum != bss)) {
389*7c478bd9Sstevel@tonic-gate 				fprintf(stderr, "namelist error on <%s>\n",
390*7c478bd9Sstevel@tonic-gate 				    nlptr->n_name);
391*7c478bd9Sstevel@tonic-gate 				/* return (1); */
392*7c478bd9Sstevel@tonic-gate 			}
393*7c478bd9Sstevel@tonic-gate 		}
394*7c478bd9Sstevel@tonic-gate 		if (SYM_VALUE(vs)) {
395*7c478bd9Sstevel@tonic-gate 			MEMSEEK(vs);
396*7c478bd9Sstevel@tonic-gate 			MEMREAD(v);
397*7c478bd9Sstevel@tonic-gate 		}
398*7c478bd9Sstevel@tonic-gate 		printf("%8d	maximum memory allowed in buffer cache "
399*7c478bd9Sstevel@tonic-gate 		    "(bufhwm)\n", v.v_bufhwm * 1024);
400*7c478bd9Sstevel@tonic-gate 		printf("%8d	maximum number of processes (v.v_proc)\n",
401*7c478bd9Sstevel@tonic-gate 		    v.v_proc);
402*7c478bd9Sstevel@tonic-gate 		printf("%8d	maximum global priority in sys class "
403*7c478bd9Sstevel@tonic-gate 		    "(MAXCLSYSPRI)\n", v.v_maxsyspri);
404*7c478bd9Sstevel@tonic-gate 		printf("%8d	maximum processes per user id (v.v_maxup)\n",
405*7c478bd9Sstevel@tonic-gate 		    v.v_maxup);
406*7c478bd9Sstevel@tonic-gate 		printf("%8d	auto update time limit in seconds (NAUTOUP)\n",
407*7c478bd9Sstevel@tonic-gate 		    v.v_autoup);
408*7c478bd9Sstevel@tonic-gate 		if (SYM_VALUE(tu)) {
409*7c478bd9Sstevel@tonic-gate 			MEMSEEK(tu);
410*7c478bd9Sstevel@tonic-gate 			MEMREAD(tune);
411*7c478bd9Sstevel@tonic-gate 		}
412*7c478bd9Sstevel@tonic-gate 		printf("%8d	page stealing low water mark (GPGSLO)\n",
413*7c478bd9Sstevel@tonic-gate 		    tune.t_gpgslo);
414*7c478bd9Sstevel@tonic-gate 		printf("%8d	fsflush run rate (FSFLUSHR)\n",
415*7c478bd9Sstevel@tonic-gate 		    tune.t_fsflushr);
416*7c478bd9Sstevel@tonic-gate 		printf("%8d	minimum resident memory for avoiding "
417*7c478bd9Sstevel@tonic-gate 		    "deadlock (MINARMEM)\n", tune.t_minarmem);
418*7c478bd9Sstevel@tonic-gate 		printf("%8d	minimum swapable memory for avoiding deadlock "
419*7c478bd9Sstevel@tonic-gate 		    "(MINASMEM)\n", tune.t_minasmem);
420*7c478bd9Sstevel@tonic-gate 	}
421*7c478bd9Sstevel@tonic-gate 
422*7c478bd9Sstevel@tonic-gate 	printf("*\n* Utsname Tunables\n*\n");
423*7c478bd9Sstevel@tonic-gate 	if (sysfile && SYM_VALUE(utsnm)) {
424*7c478bd9Sstevel@tonic-gate 		MEMSEEK(utsnm);
425*7c478bd9Sstevel@tonic-gate 		MEMREAD(utsname);
426*7c478bd9Sstevel@tonic-gate 	}
427*7c478bd9Sstevel@tonic-gate 	printf("%8s  release (REL)\n", utsname.release);
428*7c478bd9Sstevel@tonic-gate 	printf("%8s  node name (NODE)\n", utsname.nodename);
429*7c478bd9Sstevel@tonic-gate 	printf("%8s  system name (SYS)\n", utsname.sysname);
430*7c478bd9Sstevel@tonic-gate 	printf("%8s  version (VER)\n", utsname.version);
431*7c478bd9Sstevel@tonic-gate 
432*7c478bd9Sstevel@tonic-gate 	if (sysfile) {
433*7c478bd9Sstevel@tonic-gate 		printf("*\n* Process Resource Limit Tunables "
434*7c478bd9Sstevel@tonic-gate 		    "(Current:Maximum)\n*\n");
435*7c478bd9Sstevel@tonic-gate 		if (SYM_VALUE(fd_cur)) {
436*7c478bd9Sstevel@tonic-gate 			MEMSEEK(fd_cur);
437*7c478bd9Sstevel@tonic-gate 			MEMREAD(rlim_fd_cur);
438*7c478bd9Sstevel@tonic-gate 		}
439*7c478bd9Sstevel@tonic-gate 		if (SYM_VALUE(fd_max)) {
440*7c478bd9Sstevel@tonic-gate 			MEMSEEK(fd_max);
441*7c478bd9Sstevel@tonic-gate 			MEMREAD(rlim_fd_max);
442*7c478bd9Sstevel@tonic-gate 		}
443*7c478bd9Sstevel@tonic-gate 
444*7c478bd9Sstevel@tonic-gate 		printf("0x%16.16x:", rlim_fd_cur);
445*7c478bd9Sstevel@tonic-gate 		printf("0x%16.16x", rlim_fd_max);
446*7c478bd9Sstevel@tonic-gate 		printf("\tfile descriptors\n");
447*7c478bd9Sstevel@tonic-gate 
448*7c478bd9Sstevel@tonic-gate 		printf("*\n* Streams Tunables\n*\n");
449*7c478bd9Sstevel@tonic-gate 		if (SYM_VALUE(pnstrpush)) {
450*7c478bd9Sstevel@tonic-gate 			MEMSEEK(pnstrpush);	MEMREAD(nstrpush);
451*7c478bd9Sstevel@tonic-gate 			printf("%6d	maximum number of pushes allowed "
452*7c478bd9Sstevel@tonic-gate 			    "(NSTRPUSH)\n", nstrpush);
453*7c478bd9Sstevel@tonic-gate 		}
454*7c478bd9Sstevel@tonic-gate 		if (SYM_VALUE(pstrmsgsz)) {
455*7c478bd9Sstevel@tonic-gate 			MEMSEEK(pstrmsgsz);	MEMREAD(strmsgsz);
456*7c478bd9Sstevel@tonic-gate 			printf("%6ld	maximum stream message size "
457*7c478bd9Sstevel@tonic-gate 			    "(STRMSGSZ)\n", strmsgsz);
458*7c478bd9Sstevel@tonic-gate 		}
459*7c478bd9Sstevel@tonic-gate 		if (SYM_VALUE(pstrctlsz)) {
460*7c478bd9Sstevel@tonic-gate 			MEMSEEK(pstrctlsz);	MEMREAD(strctlsz);
461*7c478bd9Sstevel@tonic-gate 			printf("%6ld	max size of ctl part of message "
462*7c478bd9Sstevel@tonic-gate 			    "(STRCTLSZ)\n", strctlsz);
463*7c478bd9Sstevel@tonic-gate 		}
464*7c478bd9Sstevel@tonic-gate 	}
465*7c478bd9Sstevel@tonic-gate 
466*7c478bd9Sstevel@tonic-gate 	sysvipc("msgsys", "Messages");
467*7c478bd9Sstevel@tonic-gate 	sysvipc("semsys", "Semaphores");
468*7c478bd9Sstevel@tonic-gate 	sysvipc("shmsys", "Shared Memory");
469*7c478bd9Sstevel@tonic-gate 
470*7c478bd9Sstevel@tonic-gate 	if (sysfile) {
471*7c478bd9Sstevel@tonic-gate 		if (SYM_VALUE(pts_maxupri)) {
472*7c478bd9Sstevel@tonic-gate 			printf("*\n* Time Sharing Scheduler Tunables\n*\n");
473*7c478bd9Sstevel@tonic-gate 			MEMSEEK(pts_maxupri);	MEMREAD(ts_maxupri);
474*7c478bd9Sstevel@tonic-gate 			printf("%d	maximum time sharing user "
475*7c478bd9Sstevel@tonic-gate 			    "priority (TSMAXUPRI)\n", ts_maxupri);
476*7c478bd9Sstevel@tonic-gate 		}
477*7c478bd9Sstevel@tonic-gate 
478*7c478bd9Sstevel@tonic-gate 		if (SYM_VALUE(psys_name)) {
479*7c478bd9Sstevel@tonic-gate 			MEMSEEK(psys_name);	MEMREAD(sys_name);
480*7c478bd9Sstevel@tonic-gate 			printf("%s	system class name (SYS_NAME)\n",
481*7c478bd9Sstevel@tonic-gate 			    sys_name);
482*7c478bd9Sstevel@tonic-gate 		}
483*7c478bd9Sstevel@tonic-gate 
484*7c478bd9Sstevel@tonic-gate 		if (elfd)
485*7c478bd9Sstevel@tonic-gate 			elf_end(elfd);
486*7c478bd9Sstevel@tonic-gate 	}
487*7c478bd9Sstevel@tonic-gate 	return (0);
488*7c478bd9Sstevel@tonic-gate }
489*7c478bd9Sstevel@tonic-gate 
490*7c478bd9Sstevel@tonic-gate /*
491*7c478bd9Sstevel@tonic-gate  * setup - add an entry to a namelist structure array
492*7c478bd9Sstevel@tonic-gate  */
493*7c478bd9Sstevel@tonic-gate int
494*7c478bd9Sstevel@tonic-gate setup(char *nam)
495*7c478bd9Sstevel@tonic-gate {
496*7c478bd9Sstevel@tonic-gate 	int idx;
497*7c478bd9Sstevel@tonic-gate 
498*7c478bd9Sstevel@tonic-gate 	if (nlptr >= &nl[nlsize]) {
499*7c478bd9Sstevel@tonic-gate 		if ((nl = (struct nlist *)realloc(nl,
500*7c478bd9Sstevel@tonic-gate 		    (nlsize + EXPAND) * sizeof (struct nlist))) == NULL) {
501*7c478bd9Sstevel@tonic-gate 			fprintf(stderr, "Namelist space allocation failed\n");
502*7c478bd9Sstevel@tonic-gate 			exit(1);
503*7c478bd9Sstevel@tonic-gate 		}
504*7c478bd9Sstevel@tonic-gate 		nlptr = &nl[nlsize];
505*7c478bd9Sstevel@tonic-gate 		nlsize += EXPAND;
506*7c478bd9Sstevel@tonic-gate 	}
507*7c478bd9Sstevel@tonic-gate 
508*7c478bd9Sstevel@tonic-gate 	nlptr->n_name = malloc(strlen(nam) + 1); /* pointer to next string */
509*7c478bd9Sstevel@tonic-gate 	strcpy(nlptr->n_name, nam);	/* move name into string table */
510*7c478bd9Sstevel@tonic-gate 	nlptr->n_type = 0;
511*7c478bd9Sstevel@tonic-gate 	nlptr->n_value = 0;
512*7c478bd9Sstevel@tonic-gate 	idx = nlptr++ - nl;
513*7c478bd9Sstevel@tonic-gate 	return (idx);
514*7c478bd9Sstevel@tonic-gate }
515*7c478bd9Sstevel@tonic-gate 
516*7c478bd9Sstevel@tonic-gate /*
517*7c478bd9Sstevel@tonic-gate  * Handle the configured devices
518*7c478bd9Sstevel@tonic-gate  */
519*7c478bd9Sstevel@tonic-gate void
520*7c478bd9Sstevel@tonic-gate devices(void)
521*7c478bd9Sstevel@tonic-gate {
522*7c478bd9Sstevel@tonic-gate 	setegid(egid);
523*7c478bd9Sstevel@tonic-gate 	sysdef_devinfo();
524*7c478bd9Sstevel@tonic-gate 	setegid(getgid());
525*7c478bd9Sstevel@tonic-gate }
526*7c478bd9Sstevel@tonic-gate 
527*7c478bd9Sstevel@tonic-gate char	*LS_MODULES = "/bin/ls -R -p -i -1 ";
528*7c478bd9Sstevel@tonic-gate char	*MODULES_TMPFILE = "/tmp/sysdef.sort.XXXXXX";
529*7c478bd9Sstevel@tonic-gate 
530*7c478bd9Sstevel@tonic-gate void
531*7c478bd9Sstevel@tonic-gate modules()
532*7c478bd9Sstevel@tonic-gate {
533*7c478bd9Sstevel@tonic-gate 	int i;
534*7c478bd9Sstevel@tonic-gate 	int n_dirs = 0;
535*7c478bd9Sstevel@tonic-gate 	ino_t *inodes;
536*7c478bd9Sstevel@tonic-gate 	char *curr, *next;
537*7c478bd9Sstevel@tonic-gate 	char **dirs;
538*7c478bd9Sstevel@tonic-gate 	char *modpath, *ls_cmd;
539*7c478bd9Sstevel@tonic-gate 	char *tmpf;
540*7c478bd9Sstevel@tonic-gate 	int curr_len, modpathlen;
541*7c478bd9Sstevel@tonic-gate 	int ls_cmd_len = strlen(LS_MODULES);
542*7c478bd9Sstevel@tonic-gate 	int sfd;
543*7c478bd9Sstevel@tonic-gate 
544*7c478bd9Sstevel@tonic-gate 	if ((modctl(MODGETPATHLEN, NULL, &modpathlen)) != 0) {
545*7c478bd9Sstevel@tonic-gate 		fprintf(stderr, "sysdef: fail to get module path length\n");
546*7c478bd9Sstevel@tonic-gate 		exit(1);
547*7c478bd9Sstevel@tonic-gate 	}
548*7c478bd9Sstevel@tonic-gate 	if ((modpath = malloc(modpathlen + 1)) == NULL) {
549*7c478bd9Sstevel@tonic-gate 		fprintf(stderr, "sysdef: malloc failed\n");
550*7c478bd9Sstevel@tonic-gate 		exit(1);
551*7c478bd9Sstevel@tonic-gate 	}
552*7c478bd9Sstevel@tonic-gate 	if (modctl(MODGETPATH, NULL, modpath) != 0) {
553*7c478bd9Sstevel@tonic-gate 		fprintf(stderr, "sysdef: fail to get module path\n");
554*7c478bd9Sstevel@tonic-gate 		exit(1);
555*7c478bd9Sstevel@tonic-gate 	}
556*7c478bd9Sstevel@tonic-gate 
557*7c478bd9Sstevel@tonic-gate 	/*
558*7c478bd9Sstevel@tonic-gate 	 * Figure out number of directory entries in modpath.
559*7c478bd9Sstevel@tonic-gate 	 * Module paths are stored in a space separated string
560*7c478bd9Sstevel@tonic-gate 	 */
561*7c478bd9Sstevel@tonic-gate 	curr = modpath;
562*7c478bd9Sstevel@tonic-gate 	while (curr) {
563*7c478bd9Sstevel@tonic-gate 		n_dirs++;
564*7c478bd9Sstevel@tonic-gate 		curr = strchr(curr + 1, ' ');
565*7c478bd9Sstevel@tonic-gate 	}
566*7c478bd9Sstevel@tonic-gate 
567*7c478bd9Sstevel@tonic-gate 	if (((inodes = (ino_t *)malloc(n_dirs * sizeof (ino_t))) == NULL) ||
568*7c478bd9Sstevel@tonic-gate 	    ((dirs = (char **)malloc(n_dirs * sizeof (char *))) == NULL)) {
569*7c478bd9Sstevel@tonic-gate 		fprintf(stderr, "sysdef: malloc failed\n");
570*7c478bd9Sstevel@tonic-gate 		exit(1);
571*7c478bd9Sstevel@tonic-gate 	}
572*7c478bd9Sstevel@tonic-gate 
573*7c478bd9Sstevel@tonic-gate 	if ((tmpf = malloc(strlen(MODULES_TMPFILE) + 1)) == NULL) {
574*7c478bd9Sstevel@tonic-gate 		fprintf(stderr, "sysdef: malloc failed\n");
575*7c478bd9Sstevel@tonic-gate 		exit(1);
576*7c478bd9Sstevel@tonic-gate 	}
577*7c478bd9Sstevel@tonic-gate 
578*7c478bd9Sstevel@tonic-gate 	curr = modpath;
579*7c478bd9Sstevel@tonic-gate 	for (i = 0; i < n_dirs; i++) {
580*7c478bd9Sstevel@tonic-gate 		int j, len, inode, ino;
581*7c478bd9Sstevel@tonic-gate 		char line[100], path[100], *pathptr = "";
582*7c478bd9Sstevel@tonic-gate 		char srtbuf[100], *sorted_fname;
583*7c478bd9Sstevel@tonic-gate 		FILE *lspipe, *srtpipe, *fp;
584*7c478bd9Sstevel@tonic-gate 		struct stat stat_buf;
585*7c478bd9Sstevel@tonic-gate 
586*7c478bd9Sstevel@tonic-gate 		if (next = strchr(curr, ' ')) {
587*7c478bd9Sstevel@tonic-gate 			*next = '\0';
588*7c478bd9Sstevel@tonic-gate 		}
589*7c478bd9Sstevel@tonic-gate 
590*7c478bd9Sstevel@tonic-gate 		/*
591*7c478bd9Sstevel@tonic-gate 		 * Make sure the module path is present.
592*7c478bd9Sstevel@tonic-gate 		 */
593*7c478bd9Sstevel@tonic-gate 		if (stat(curr, &stat_buf) == -1) {
594*7c478bd9Sstevel@tonic-gate 			curr = next ? next + 1 : NULL;
595*7c478bd9Sstevel@tonic-gate 			inodes[i] = (ino_t)-1;
596*7c478bd9Sstevel@tonic-gate 			continue;
597*7c478bd9Sstevel@tonic-gate 		}
598*7c478bd9Sstevel@tonic-gate 
599*7c478bd9Sstevel@tonic-gate 		/*
600*7c478bd9Sstevel@tonic-gate 		 * On sparcs, /platform/SUNW,... can be symbolic link to
601*7c478bd9Sstevel@tonic-gate 		 * /platform/sun4x. We check the inode number of directory
602*7c478bd9Sstevel@tonic-gate 		 * and skip any duplication.
603*7c478bd9Sstevel@tonic-gate 		 */
604*7c478bd9Sstevel@tonic-gate 		dirs[i] = curr;
605*7c478bd9Sstevel@tonic-gate 		inodes[i] = stat_buf.st_ino;
606*7c478bd9Sstevel@tonic-gate 
607*7c478bd9Sstevel@tonic-gate 		for (j = 0; inodes[i] != inodes[j]; j++)
608*7c478bd9Sstevel@tonic-gate 			;
609*7c478bd9Sstevel@tonic-gate 		if (j != i) {
610*7c478bd9Sstevel@tonic-gate 			curr = next ? next + 1 : NULL;
611*7c478bd9Sstevel@tonic-gate 			continue;
612*7c478bd9Sstevel@tonic-gate 		}
613*7c478bd9Sstevel@tonic-gate 
614*7c478bd9Sstevel@tonic-gate 		printf("*\n* Loadable Object Path = %s\n*\n", curr);
615*7c478bd9Sstevel@tonic-gate 
616*7c478bd9Sstevel@tonic-gate 		curr_len = strlen(curr);
617*7c478bd9Sstevel@tonic-gate 		if ((ls_cmd = malloc(ls_cmd_len + curr_len + 1)) == NULL) {
618*7c478bd9Sstevel@tonic-gate 			fprintf(stderr, "sysdef: malloc failed\n");
619*7c478bd9Sstevel@tonic-gate 			exit(1);
620*7c478bd9Sstevel@tonic-gate 		}
621*7c478bd9Sstevel@tonic-gate 
622*7c478bd9Sstevel@tonic-gate 		(void) sprintf(ls_cmd, "%s%s", LS_MODULES, curr);
623*7c478bd9Sstevel@tonic-gate 
624*7c478bd9Sstevel@tonic-gate 		/*
625*7c478bd9Sstevel@tonic-gate 		 * List the loadable objects in the directory tree, sorting
626*7c478bd9Sstevel@tonic-gate 		 * them by inode so as to note any hard links.  A temporary
627*7c478bd9Sstevel@tonic-gate 		 * file in /tmp  is used to store output from sort before
628*7c478bd9Sstevel@tonic-gate 		 * listing.
629*7c478bd9Sstevel@tonic-gate 		 */
630*7c478bd9Sstevel@tonic-gate 		if ((lspipe = popen(ls_cmd, "r")) == NULL) {
631*7c478bd9Sstevel@tonic-gate 			fprintf(stderr, "sysdef: cannot open ls pipe\n");
632*7c478bd9Sstevel@tonic-gate 			exit(1);
633*7c478bd9Sstevel@tonic-gate 		}
634*7c478bd9Sstevel@tonic-gate 		free(ls_cmd);
635*7c478bd9Sstevel@tonic-gate 
636*7c478bd9Sstevel@tonic-gate 		(void) strcpy(tmpf, MODULES_TMPFILE);
637*7c478bd9Sstevel@tonic-gate 		if ((sorted_fname = mktemp(tmpf)) == NULL ||
638*7c478bd9Sstevel@tonic-gate 		    (strcmp(sorted_fname, "") == 0)) {
639*7c478bd9Sstevel@tonic-gate 			fprintf(stderr,
640*7c478bd9Sstevel@tonic-gate 			    "sysdef: cannot create unique tmp file name\n");
641*7c478bd9Sstevel@tonic-gate 			exit(1);
642*7c478bd9Sstevel@tonic-gate 		}
643*7c478bd9Sstevel@tonic-gate 
644*7c478bd9Sstevel@tonic-gate 		if ((sfd = open(sorted_fname, O_RDWR|O_CREAT|O_EXCL,
645*7c478bd9Sstevel@tonic-gate 		    0600)) == -1) {
646*7c478bd9Sstevel@tonic-gate 			fprintf(stderr, "sysdef: cannot open %s\n",
647*7c478bd9Sstevel@tonic-gate 			    sorted_fname);
648*7c478bd9Sstevel@tonic-gate 			exit(1);
649*7c478bd9Sstevel@tonic-gate 		}
650*7c478bd9Sstevel@tonic-gate 
651*7c478bd9Sstevel@tonic-gate 		sprintf(srtbuf, "/bin/sort - > %s", sorted_fname);
652*7c478bd9Sstevel@tonic-gate 		if ((srtpipe = popen(srtbuf, "w")) == NULL) {
653*7c478bd9Sstevel@tonic-gate 			fprintf(stderr, "sysdef: cannot open sort pipe\n");
654*7c478bd9Sstevel@tonic-gate 			exit(1);
655*7c478bd9Sstevel@tonic-gate 		}
656*7c478bd9Sstevel@tonic-gate 
657*7c478bd9Sstevel@tonic-gate 		while (fgets(line, 99, lspipe) != NULL) {
658*7c478bd9Sstevel@tonic-gate 			char *tmp;
659*7c478bd9Sstevel@tonic-gate 			/*
660*7c478bd9Sstevel@tonic-gate 			 * 'line' has <cr>, skip blank lines & dir entries
661*7c478bd9Sstevel@tonic-gate 			 */
662*7c478bd9Sstevel@tonic-gate 			if (((len = strlen(line)) <= 1) ||
663*7c478bd9Sstevel@tonic-gate 			    (line[len-2] == '/'))
664*7c478bd9Sstevel@tonic-gate 				continue;
665*7c478bd9Sstevel@tonic-gate 
666*7c478bd9Sstevel@tonic-gate 			/* remember path of each subdirectory */
667*7c478bd9Sstevel@tonic-gate 
668*7c478bd9Sstevel@tonic-gate 			if (line[0] == '/') {
669*7c478bd9Sstevel@tonic-gate 				(void) strcpy(path, &line[curr_len]);
670*7c478bd9Sstevel@tonic-gate 				tmp = strtok(&path[1], ":");
671*7c478bd9Sstevel@tonic-gate 				if ((tmp == NULL) || (tmp[0] == '\n')) {
672*7c478bd9Sstevel@tonic-gate 					continue;
673*7c478bd9Sstevel@tonic-gate 				}
674*7c478bd9Sstevel@tonic-gate 				pathptr = &path[1];
675*7c478bd9Sstevel@tonic-gate 				(void) strcat(pathptr, "/");
676*7c478bd9Sstevel@tonic-gate 				continue;
677*7c478bd9Sstevel@tonic-gate 			} else {
678*7c478bd9Sstevel@tonic-gate 				char *tmp1 = strtok(line, " ");
679*7c478bd9Sstevel@tonic-gate 				tmp = strtok(NULL, "\n");
680*7c478bd9Sstevel@tonic-gate 				/*
681*7c478bd9Sstevel@tonic-gate 				 * eliminate .conf file
682*7c478bd9Sstevel@tonic-gate 				 */
683*7c478bd9Sstevel@tonic-gate 				if (strstr(tmp, ".conf")) {
684*7c478bd9Sstevel@tonic-gate 					continue;
685*7c478bd9Sstevel@tonic-gate 				}
686*7c478bd9Sstevel@tonic-gate 				/*
687*7c478bd9Sstevel@tonic-gate 				 * Printing the (inode, path, module)
688*7c478bd9Sstevel@tonic-gate 				 * ripple.
689*7c478bd9Sstevel@tonic-gate 				 */
690*7c478bd9Sstevel@tonic-gate 				fprintf(srtpipe, "%s %s%s\n",
691*7c478bd9Sstevel@tonic-gate 				    tmp1, pathptr, tmp);
692*7c478bd9Sstevel@tonic-gate 			}
693*7c478bd9Sstevel@tonic-gate 		}
694*7c478bd9Sstevel@tonic-gate 		(void) pclose(lspipe);
695*7c478bd9Sstevel@tonic-gate 		(void) pclose(srtpipe);
696*7c478bd9Sstevel@tonic-gate 
697*7c478bd9Sstevel@tonic-gate 		/*
698*7c478bd9Sstevel@tonic-gate 		 * A note on data synchronization. We opened sfd above,
699*7c478bd9Sstevel@tonic-gate 		 * before calling popen, to ensure that the tempfile
700*7c478bd9Sstevel@tonic-gate 		 * was created exclusively to prevent a malicious user
701*7c478bd9Sstevel@tonic-gate 		 * from creating a link in /tmp to make us overwrite
702*7c478bd9Sstevel@tonic-gate 		 * another file. We have never read from sfd, there
703*7c478bd9Sstevel@tonic-gate 		 * can be no stale data cached anywhere.
704*7c478bd9Sstevel@tonic-gate 		 */
705*7c478bd9Sstevel@tonic-gate 		if ((fp = fdopen(sfd, "r")) == NULL) {
706*7c478bd9Sstevel@tonic-gate 			fprintf(stderr, "sysdef: cannot open sorted file: %s",
707*7c478bd9Sstevel@tonic-gate 			    sorted_fname);
708*7c478bd9Sstevel@tonic-gate 			exit(1);
709*7c478bd9Sstevel@tonic-gate 		}
710*7c478bd9Sstevel@tonic-gate 		inode = -1;
711*7c478bd9Sstevel@tonic-gate 		while (fgets(line, 99, fp) != NULL) {
712*7c478bd9Sstevel@tonic-gate 
713*7c478bd9Sstevel@tonic-gate 			sscanf(line, "%d %s",  &ino, path);
714*7c478bd9Sstevel@tonic-gate 			if (ino == inode)
715*7c478bd9Sstevel@tonic-gate 				printf("\thard link:  ");
716*7c478bd9Sstevel@tonic-gate 			printf("%s\n", path);
717*7c478bd9Sstevel@tonic-gate 			inode = ino;
718*7c478bd9Sstevel@tonic-gate 		}
719*7c478bd9Sstevel@tonic-gate 		(void) fclose(fp);
720*7c478bd9Sstevel@tonic-gate 		(void) unlink(sorted_fname);
721*7c478bd9Sstevel@tonic-gate 		curr = next ? next + 1 : NULL;
722*7c478bd9Sstevel@tonic-gate 	}
723*7c478bd9Sstevel@tonic-gate 	free(tmpf);
724*7c478bd9Sstevel@tonic-gate 	free(modpath);
725*7c478bd9Sstevel@tonic-gate }
726*7c478bd9Sstevel@tonic-gate 
727*7c478bd9Sstevel@tonic-gate void
728*7c478bd9Sstevel@tonic-gate sysdev(void)
729*7c478bd9Sstevel@tonic-gate {
730*7c478bd9Sstevel@tonic-gate 	printf("  swap files\n");
731*7c478bd9Sstevel@tonic-gate 	fflush(stdout);
732*7c478bd9Sstevel@tonic-gate 	if (system("/usr/sbin/swap -l") < 0)
733*7c478bd9Sstevel@tonic-gate 		fprintf(stderr, "unknown swap file(s)\n");
734*7c478bd9Sstevel@tonic-gate }
735*7c478bd9Sstevel@tonic-gate 
736*7c478bd9Sstevel@tonic-gate void
737*7c478bd9Sstevel@tonic-gate memseek(int sym)
738*7c478bd9Sstevel@tonic-gate {
739*7c478bd9Sstevel@tonic-gate 	Elf_Scn *scn;
740*7c478bd9Sstevel@tonic-gate 	Shdr *eshdr;
741*7c478bd9Sstevel@tonic-gate 	long eoff;
742*7c478bd9Sstevel@tonic-gate 
743*7c478bd9Sstevel@tonic-gate 	if (incore) {
744*7c478bd9Sstevel@tonic-gate 		if ((fseek(memfile, nl[sym].n_value, 0)) != 0) {
745*7c478bd9Sstevel@tonic-gate 			fprintf(stderr, "%s: fseek error (in memseek)\n", mem);
746*7c478bd9Sstevel@tonic-gate 			exit(1);
747*7c478bd9Sstevel@tonic-gate 		}
748*7c478bd9Sstevel@tonic-gate 	} else {
749*7c478bd9Sstevel@tonic-gate 		if ((scn = elf_getscn(elfd, nl[sym].n_scnum)) == NULL) {
750*7c478bd9Sstevel@tonic-gate 			fprintf(stderr, "%s: Error reading Scn %d (%s)\n",
751*7c478bd9Sstevel@tonic-gate 				os, nl[sym].n_scnum, elf_errmsg(-1));
752*7c478bd9Sstevel@tonic-gate 			exit(1);
753*7c478bd9Sstevel@tonic-gate 		}
754*7c478bd9Sstevel@tonic-gate 
755*7c478bd9Sstevel@tonic-gate 		if ((eshdr = elf_getshdr(scn)) == NULL) {
756*7c478bd9Sstevel@tonic-gate 			fprintf(stderr, "%s: Error reading Shdr %d (%s)\n",
757*7c478bd9Sstevel@tonic-gate 				os, nl[sym].n_scnum, elf_errmsg(-1));
758*7c478bd9Sstevel@tonic-gate 			exit(1);
759*7c478bd9Sstevel@tonic-gate 		}
760*7c478bd9Sstevel@tonic-gate 
761*7c478bd9Sstevel@tonic-gate 		eoff = (long)(nl[sym].n_value - eshdr->sh_addr +
762*7c478bd9Sstevel@tonic-gate 		    eshdr->sh_offset);
763*7c478bd9Sstevel@tonic-gate 
764*7c478bd9Sstevel@tonic-gate 		if ((fseek(sysfile, eoff, 0)) != 0) {
765*7c478bd9Sstevel@tonic-gate 			fprintf(stderr, "%s: fseek error (in memseek)\n", os);
766*7c478bd9Sstevel@tonic-gate 			exit(1);
767*7c478bd9Sstevel@tonic-gate 		}
768*7c478bd9Sstevel@tonic-gate 	}
769*7c478bd9Sstevel@tonic-gate }
770*7c478bd9Sstevel@tonic-gate 
771*7c478bd9Sstevel@tonic-gate /*
772*7c478bd9Sstevel@tonic-gate  * filter out bss symbols if the reads are from the file
773*7c478bd9Sstevel@tonic-gate  */
774*7c478bd9Sstevel@tonic-gate void
775*7c478bd9Sstevel@tonic-gate getnlist(void)
776*7c478bd9Sstevel@tonic-gate {
777*7c478bd9Sstevel@tonic-gate 	struct nlist *p;
778*7c478bd9Sstevel@tonic-gate 
779*7c478bd9Sstevel@tonic-gate 	nlist(os, nl);
780*7c478bd9Sstevel@tonic-gate 
781*7c478bd9Sstevel@tonic-gate 	/*
782*7c478bd9Sstevel@tonic-gate 	 * The nlist is done. If any symbol is a bss
783*7c478bd9Sstevel@tonic-gate 	 * and we are not reading from incore, zero
784*7c478bd9Sstevel@tonic-gate 	 * the n_value field. (Won't be printed if
785*7c478bd9Sstevel@tonic-gate 	 * n_value == 0.)
786*7c478bd9Sstevel@tonic-gate 	 */
787*7c478bd9Sstevel@tonic-gate 	if (!incore) {
788*7c478bd9Sstevel@tonic-gate 		for (p = nl; p->n_name && p->n_name[0]; p++) {
789*7c478bd9Sstevel@tonic-gate 			if (p->n_scnum == bss) {
790*7c478bd9Sstevel@tonic-gate 				p->n_value = 0;
791*7c478bd9Sstevel@tonic-gate 			}
792*7c478bd9Sstevel@tonic-gate 		}
793*7c478bd9Sstevel@tonic-gate 	}
794*7c478bd9Sstevel@tonic-gate }
795