xref: /onnv-gate/usr/src/cmd/sgs/crle/common/config.c (revision 1976:f0691a145b7e)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*1976Sab196087  * Common Development and Distribution License (the "License").
6*1976Sab196087  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
210Sstevel@tonic-gate /*
22*1976Sab196087  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
230Sstevel@tonic-gate  * Use is subject to license terms.
240Sstevel@tonic-gate  */
250Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
260Sstevel@tonic-gate 
270Sstevel@tonic-gate #include	<sys/mman.h>
280Sstevel@tonic-gate #include	<sys/types.h>
290Sstevel@tonic-gate #include	<fcntl.h>
300Sstevel@tonic-gate #include	<unistd.h>
310Sstevel@tonic-gate #include	<errno.h>
320Sstevel@tonic-gate #include	<stdio.h>
330Sstevel@tonic-gate #include	<string.h>
340Sstevel@tonic-gate #include	"rtc.h"
350Sstevel@tonic-gate #include	"_crle.h"
360Sstevel@tonic-gate #include	"msg.h"
370Sstevel@tonic-gate 
380Sstevel@tonic-gate 
390Sstevel@tonic-gate #define	MAXNBKTS 10007
400Sstevel@tonic-gate 
410Sstevel@tonic-gate static const int hashsize[] = {
420Sstevel@tonic-gate 	3,	7,	13,	31,	53,	67,	83,	97,
430Sstevel@tonic-gate 	101,	151,	211,	251,	307,	353,	401,	457,	503,
440Sstevel@tonic-gate 	557,	601,	653,	701,	751,	809,	859,	907,	953,
450Sstevel@tonic-gate 	1009,	1103,	1201,	1301,	1409,	1511,	1601,	1709,	1801,
460Sstevel@tonic-gate 	1901,	2003,	2111,	2203,	2309,	2411,	2503,	2609,	2707,
470Sstevel@tonic-gate 	2801,	2903,	3001,	3109,	3203,	3301,	3407,	3511,	3607,
480Sstevel@tonic-gate 	3701,	3803,	3907,	4001,	5003,   6101,   7001,   8101,   9001,
490Sstevel@tonic-gate 	MAXNBKTS
500Sstevel@tonic-gate };
510Sstevel@tonic-gate 
520Sstevel@tonic-gate /*
530Sstevel@tonic-gate  * Generate a configuration file from the internal configuration information.
540Sstevel@tonic-gate  * (very link-editor like).
550Sstevel@tonic-gate  */
56238Sseizo int
570Sstevel@tonic-gate genconfig(Crle_desc * crle)
580Sstevel@tonic-gate {
590Sstevel@tonic-gate 	int		ndx, bkt;
600Sstevel@tonic-gate 	size_t		size, hashoff = 0, stroff = 0, objoff = 0;
610Sstevel@tonic-gate 	size_t		diroff = 0, fileoff = 0, envoff = 0;
620Sstevel@tonic-gate 	size_t		fltroff = 0, flteoff = 0;
630Sstevel@tonic-gate 	Addr		addr;
64*1976Sab196087 	Rtc_id		*id;
650Sstevel@tonic-gate 	Rtc_head	*head;
660Sstevel@tonic-gate 	Word		*hashtbl, * hashbkt, * hashchn, hashbkts = 0;
670Sstevel@tonic-gate 	char		*strtbl, *_strtbl;
680Sstevel@tonic-gate 	Rtc_obj		*objtbl;
690Sstevel@tonic-gate 	Rtc_dir		*dirtbl;
700Sstevel@tonic-gate 	Rtc_file	*filetbl;
710Sstevel@tonic-gate 	Rtc_env		*envtbl;
720Sstevel@tonic-gate 	Rtc_fltr	*fltrtbl;
730Sstevel@tonic-gate 	Rtc_flte	*fltetbl, * _fltetbl;
740Sstevel@tonic-gate 	Hash_tbl	*stbl = crle->c_strtbl;
750Sstevel@tonic-gate 	Hash_ent	*ent;
760Sstevel@tonic-gate 
770Sstevel@tonic-gate 	/*
780Sstevel@tonic-gate 	 * Establish the size of the configuration file.
790Sstevel@tonic-gate 	 */
800Sstevel@tonic-gate 	size = S_ROUND(sizeof (Rtc_head), sizeof (Word));
810Sstevel@tonic-gate 
820Sstevel@tonic-gate 	if (crle->c_hashstrnum) {
830Sstevel@tonic-gate 		hashoff = size;
840Sstevel@tonic-gate 
850Sstevel@tonic-gate 		/*
860Sstevel@tonic-gate 		 * Increment the hash string number to account for an initial
870Sstevel@tonic-gate 		 * null entry.  Indexes start at 1 to simplify hash lookup.
880Sstevel@tonic-gate 		 */
890Sstevel@tonic-gate 		crle->c_hashstrnum++;
900Sstevel@tonic-gate 
910Sstevel@tonic-gate 		/*
920Sstevel@tonic-gate 		 * Determine the hash table size.  Establish the number of
930Sstevel@tonic-gate 		 * buckets from the number of strings, the number of chains is
940Sstevel@tonic-gate 		 * equivalent to the number of objects, and two entries for the
950Sstevel@tonic-gate 		 * nbucket and nchain entries.
960Sstevel@tonic-gate 		 */
970Sstevel@tonic-gate 		for (ndx = 0; ndx < (sizeof (hashsize) / sizeof (int)); ndx++) {
980Sstevel@tonic-gate 			if (crle->c_hashstrnum > hashsize[ndx])
990Sstevel@tonic-gate 				continue;
1000Sstevel@tonic-gate 			hashbkts = hashsize[ndx];
1010Sstevel@tonic-gate 			break;
1020Sstevel@tonic-gate 		}
1030Sstevel@tonic-gate 		if (hashbkts == 0)
1040Sstevel@tonic-gate 			hashbkts = MAXNBKTS;
1050Sstevel@tonic-gate 		size += ((2 + hashbkts + crle->c_hashstrnum) * sizeof (Word));
1060Sstevel@tonic-gate 		size = S_ROUND(size, sizeof (Lword));
1070Sstevel@tonic-gate 		objoff = size;
1080Sstevel@tonic-gate 
1090Sstevel@tonic-gate 		/*
1100Sstevel@tonic-gate 		 * Add the object table size (account for an 8-byte alignment
1110Sstevel@tonic-gate 		 * requirement for each object).
1120Sstevel@tonic-gate 		 */
1130Sstevel@tonic-gate 		size += (crle->c_hashstrnum *
1140Sstevel@tonic-gate 		    S_ROUND(sizeof (Rtc_obj), sizeof (Lword)));
1150Sstevel@tonic-gate 
1160Sstevel@tonic-gate 		/*
1170Sstevel@tonic-gate 		 * Add the file descriptor arrays.
1180Sstevel@tonic-gate 		 */
1190Sstevel@tonic-gate 		fileoff = size;
1200Sstevel@tonic-gate 		size += S_ROUND((crle->c_filenum * sizeof (Rtc_file)),
1210Sstevel@tonic-gate 		    sizeof (Word));
1220Sstevel@tonic-gate 
1230Sstevel@tonic-gate 		/*
1240Sstevel@tonic-gate 		 * Add the directory descriptor array.
1250Sstevel@tonic-gate 		 */
1260Sstevel@tonic-gate 		diroff = size;
1270Sstevel@tonic-gate 		size += S_ROUND((crle->c_dirnum * sizeof (Rtc_dir)),
1280Sstevel@tonic-gate 		    sizeof (Word));
1290Sstevel@tonic-gate 	}
1300Sstevel@tonic-gate 
1310Sstevel@tonic-gate 	/*
1320Sstevel@tonic-gate 	 * Add any environment string array (insure zero last entry).
1330Sstevel@tonic-gate 	 */
1340Sstevel@tonic-gate 	if (crle->c_envnum) {
1350Sstevel@tonic-gate 		envoff = size;
1360Sstevel@tonic-gate 		size += S_ROUND(((crle->c_envnum + 1) * sizeof (Rtc_env)),
1370Sstevel@tonic-gate 		    sizeof (Word));
1380Sstevel@tonic-gate 	}
1390Sstevel@tonic-gate 
1400Sstevel@tonic-gate 	/*
1410Sstevel@tonic-gate 	 * Add any filter/filtee association arrays (insure zero last entry for
1420Sstevel@tonic-gate 	 * the filter array, the filtee arrays are already accounted for).
1430Sstevel@tonic-gate 	 */
1440Sstevel@tonic-gate 	if (crle->c_fltrnum) {
1450Sstevel@tonic-gate 		fltroff = size;
1460Sstevel@tonic-gate 		size += S_ROUND(((crle->c_fltrnum + 1) * sizeof (Rtc_fltr)),
1470Sstevel@tonic-gate 		    sizeof (Word));
1480Sstevel@tonic-gate 		flteoff = size;
1490Sstevel@tonic-gate 		size += S_ROUND((crle->c_fltenum * sizeof (Rtc_flte)),
1500Sstevel@tonic-gate 		    sizeof (Word));
1510Sstevel@tonic-gate 	}
1520Sstevel@tonic-gate 
1530Sstevel@tonic-gate 	/*
1540Sstevel@tonic-gate 	 * Add the string table size (this may contain library and/or secure
1550Sstevel@tonic-gate 	 * path strings, in addition to any directory/file strings).
1560Sstevel@tonic-gate 	 */
1570Sstevel@tonic-gate 	if (crle->c_strsize) {
1580Sstevel@tonic-gate 		stroff = size;
1590Sstevel@tonic-gate 		size += S_ROUND(crle->c_strsize, sizeof (Word));
1600Sstevel@tonic-gate 	}
1610Sstevel@tonic-gate 
162*1976Sab196087 	/* Account for addition of Rtc_id block at the start */
163*1976Sab196087 	if (crle->c_flags & CRLE_ADDID)
164*1976Sab196087 		size += sizeof (Rtc_id);
165*1976Sab196087 
1660Sstevel@tonic-gate 	/*
1670Sstevel@tonic-gate 	 * Truncate our temporary file now that we know its size and map it.
1680Sstevel@tonic-gate 	 */
1690Sstevel@tonic-gate 	if (ftruncate(crle->c_tempfd, size) == -1) {
1700Sstevel@tonic-gate 		int err = errno;
1710Sstevel@tonic-gate 		(void) fprintf(stderr, MSG_INTL(MSG_SYS_TRUNC),
1720Sstevel@tonic-gate 		    crle->c_name, crle->c_tempname, strerror(err));
1730Sstevel@tonic-gate 		(void) close(crle->c_tempfd);
1740Sstevel@tonic-gate 		return (1);
1750Sstevel@tonic-gate 	}
1760Sstevel@tonic-gate 	if ((addr = (Addr)mmap(0, size, (PROT_READ | PROT_WRITE), MAP_SHARED,
1770Sstevel@tonic-gate 	    crle->c_tempfd, 0)) == (Addr)-1) {
1780Sstevel@tonic-gate 		int err = errno;
1790Sstevel@tonic-gate 		(void) fprintf(stderr, MSG_INTL(MSG_SYS_MMAP),
1800Sstevel@tonic-gate 		    crle->c_name, crle->c_tempname, strerror(err));
1810Sstevel@tonic-gate 		(void) close(crle->c_tempfd);
1820Sstevel@tonic-gate 		return (1);
1830Sstevel@tonic-gate 	}
1840Sstevel@tonic-gate 
1850Sstevel@tonic-gate 	/*
1860Sstevel@tonic-gate 	 * Save the mapped files info for possible dldump(3dl) updates.
1870Sstevel@tonic-gate 	 */
1880Sstevel@tonic-gate 	crle->c_tempaddr = addr;
1890Sstevel@tonic-gate 	crle->c_tempsize = size;
1900Sstevel@tonic-gate 
1910Sstevel@tonic-gate 	/*
192*1976Sab196087 	 * Rtc_id goes at the top, followed by the Rtc_head. We base
193*1976Sab196087 	 * all offset calculations relative to Rtc_head, not from
194*1976Sab196087 	 * the top of the file. This eases backwards compatability to
195*1976Sab196087 	 * older versons that lacked the Rtc_id at the top.
1960Sstevel@tonic-gate 	 */
197*1976Sab196087 	if (crle->c_flags & CRLE_ADDID) {
198*1976Sab196087 		/* The contents of the Rtc_id are all known at compile time */
199*1976Sab196087 		static const Rtc_id id_template = {
200*1976Sab196087 			RTC_ID_MAG0, RTC_ID_MAG1, RTC_ID_MAG2, RTC_ID_MAG3,
201*1976Sab196087 			M_CLASS, M_DATA, M_MACH,
202*1976Sab196087 			{ 0, 0, 0, 0, 0, 0, 0, 0, 0 } };
203*1976Sab196087 
204*1976Sab196087 		id = (Rtc_id *) addr;
205*1976Sab196087 		*id = id_template;	/* Fill in the Rtc_id data */
206*1976Sab196087 		addr += sizeof (Rtc_id);
207*1976Sab196087 	} else {
208*1976Sab196087 		id = NULL;
209*1976Sab196087 	}
210*1976Sab196087 	crle->c_tempheadaddr = addr;
2110Sstevel@tonic-gate 	head = (Rtc_head *)addr;
2120Sstevel@tonic-gate 
213*1976Sab196087 	/*
214*1976Sab196087 	 * Establish the real address of each of the structures within the file.
215*1976Sab196087 	 */
2160Sstevel@tonic-gate 	head->ch_hash = hashoff;
2170Sstevel@tonic-gate 	/* LINTED */
218*1976Sab196087 	hashtbl = (Word *)(CAST_PTRINT(char *, head->ch_hash) + addr);
2190Sstevel@tonic-gate 
2200Sstevel@tonic-gate 	head->ch_obj = objoff;
2210Sstevel@tonic-gate 	/* LINTED */
222*1976Sab196087 	objtbl = (Rtc_obj *)(CAST_PTRINT(char *, head->ch_obj) + addr);
223*1976Sab196087 	objtbl = (Rtc_obj *)S_ROUND((uintptr_t)(objtbl + 1), sizeof (Lword));
2240Sstevel@tonic-gate 
2250Sstevel@tonic-gate 	head->ch_file = fileoff;
2260Sstevel@tonic-gate 	/* LINTED */
227*1976Sab196087 	filetbl = (Rtc_file *)(CAST_PTRINT(char *, head->ch_file) + addr);
2280Sstevel@tonic-gate 
2290Sstevel@tonic-gate 	head->ch_dir = diroff;
2300Sstevel@tonic-gate 	/* LINTED */
231*1976Sab196087 	dirtbl = (Rtc_dir *)(CAST_PTRINT(char *, head->ch_dir) + addr);
2320Sstevel@tonic-gate 
2330Sstevel@tonic-gate 	head->ch_env = envoff;
2340Sstevel@tonic-gate 	/* LINTED */
235*1976Sab196087 	envtbl = (Rtc_env *)(CAST_PTRINT(char *, head->ch_env) + addr);
2360Sstevel@tonic-gate 
2370Sstevel@tonic-gate 	head->ch_fltr = fltroff;
2380Sstevel@tonic-gate 	/* LINTED */
239*1976Sab196087 	fltrtbl = (Rtc_fltr *)(CAST_PTRINT(char *, head->ch_fltr) + addr);
2400Sstevel@tonic-gate 	head->ch_flte = flteoff;
2410Sstevel@tonic-gate 	/* LINTED */
242*1976Sab196087 	fltetbl = _fltetbl =
243*1976Sab196087 		(Rtc_flte *)(CAST_PTRINT(char *, head->ch_flte) + addr);
2440Sstevel@tonic-gate 
2450Sstevel@tonic-gate 	head->ch_str = stroff;
246*1976Sab196087 	strtbl = _strtbl = (char *)(CAST_PTRINT(char *, head->ch_str) + addr);
2470Sstevel@tonic-gate 
2480Sstevel@tonic-gate 	/*
2490Sstevel@tonic-gate 	 * Fill in additional basic header information.
2500Sstevel@tonic-gate 	 */
2510Sstevel@tonic-gate 	head->ch_version = RTC_VER_CURRENT;
2520Sstevel@tonic-gate 
2530Sstevel@tonic-gate 	if (crle->c_flags & CRLE_ALTER)
2540Sstevel@tonic-gate 		head->ch_cnflags |= RTC_HDR_ALTER;
2550Sstevel@tonic-gate 	if (crle->c_flags & CRLE_DUMP) {
2560Sstevel@tonic-gate 		head->ch_cnflags |= RTC_HDR_IGNORE;
2570Sstevel@tonic-gate 		head->ch_dlflags = crle->c_dlflags;
2580Sstevel@tonic-gate 	}
259*1976Sab196087 #ifdef _ELF64
260*1976Sab196087 	head->ch_cnflags |= RTC_HDR_64;
261*1976Sab196087 #endif
2620Sstevel@tonic-gate 
2630Sstevel@tonic-gate #ifndef	SGS_PRE_UNIFIED_PROCESS
2640Sstevel@tonic-gate 	head->ch_cnflags |= RTC_HDR_UPM;
2650Sstevel@tonic-gate #endif
2660Sstevel@tonic-gate 	/*
2670Sstevel@tonic-gate 	 * If we have a hash table then there are directory and file entries
2680Sstevel@tonic-gate 	 * to process.
2690Sstevel@tonic-gate 	 */
2700Sstevel@tonic-gate 	if (crle->c_hashstrnum) {
2710Sstevel@tonic-gate 		hashtbl[0] = hashbkts;
2720Sstevel@tonic-gate 		hashtbl[1] = crle->c_hashstrnum;
2730Sstevel@tonic-gate 		hashbkt = &hashtbl[2];
2740Sstevel@tonic-gate 		hashchn = &hashtbl[2 + hashbkts];
2750Sstevel@tonic-gate 
2760Sstevel@tonic-gate 		/*
2770Sstevel@tonic-gate 		 * Insure all hash chain and directory/filename table entries
2780Sstevel@tonic-gate 		 * are cleared.
2790Sstevel@tonic-gate 		 */
2800Sstevel@tonic-gate 		(void) memset(hashchn, 0, (crle->c_hashstrnum * sizeof (Word)));
2810Sstevel@tonic-gate 		(void) memset(dirtbl, 0, (strtbl - (char *)dirtbl));
2820Sstevel@tonic-gate 
2830Sstevel@tonic-gate 		/*
2840Sstevel@tonic-gate 		 * Loop through the current string table list inspecting only
2850Sstevel@tonic-gate 		 * directories.
2860Sstevel@tonic-gate 		 */
2870Sstevel@tonic-gate 		for (ndx = 1, bkt = 0; bkt < stbl->t_size; bkt++) {
2880Sstevel@tonic-gate 			for (ent = stbl->t_entry[bkt]; ent; ent = ent->e_next) {
2890Sstevel@tonic-gate 				Word		hashval;
2900Sstevel@tonic-gate 				Hash_obj	*obj = ent->e_obj;
2910Sstevel@tonic-gate 				char		*dir = (char *)ent->e_key;
2920Sstevel@tonic-gate 				Rtc_dir		*_dirtbl;
2930Sstevel@tonic-gate 
2940Sstevel@tonic-gate 				/*
2950Sstevel@tonic-gate 				 * Skip any empty and non-directory entries.
2960Sstevel@tonic-gate 				 */
2970Sstevel@tonic-gate 				if ((obj == 0) ||
2980Sstevel@tonic-gate 				    ((obj->o_flags & RTC_OBJ_DIRENT) == 0))
2990Sstevel@tonic-gate 					continue;
3000Sstevel@tonic-gate 
3010Sstevel@tonic-gate 				/*
3020Sstevel@tonic-gate 				 * Assign basic object attributes.
3030Sstevel@tonic-gate 				 */
3040Sstevel@tonic-gate 				objtbl->co_hash = ent->e_hash;
3050Sstevel@tonic-gate 				objtbl->co_id = ent->e_id;
3060Sstevel@tonic-gate 				objtbl->co_flags = obj->o_flags | ent->e_flags;
3070Sstevel@tonic-gate 				objtbl->co_info = obj->o_info;
3080Sstevel@tonic-gate 
3090Sstevel@tonic-gate 				ent->e_cobj = objtbl;
3100Sstevel@tonic-gate 
3110Sstevel@tonic-gate 				/*
3120Sstevel@tonic-gate 				 * Assign the directory name (from its key),
3130Sstevel@tonic-gate 				 * and copy its name to the string table.
3140Sstevel@tonic-gate 				 */
3150Sstevel@tonic-gate 				objtbl->co_name = (Addr)(_strtbl - strtbl);
3160Sstevel@tonic-gate 				(void) strcpy(_strtbl, dir);
3170Sstevel@tonic-gate 				_strtbl += strlen(dir) + 1;
3180Sstevel@tonic-gate 
3190Sstevel@tonic-gate 				/*
3200Sstevel@tonic-gate 				 * Establish an entry in the directory table and
3210Sstevel@tonic-gate 				 * reserve space for its associated filename
3220Sstevel@tonic-gate 				 * entries (note, we add a trailing null file
3230Sstevel@tonic-gate 				 * entry to simplify later inspection of the
3240Sstevel@tonic-gate 				 * final configuration file.
3250Sstevel@tonic-gate 				 */
3260Sstevel@tonic-gate 				_dirtbl = &dirtbl[ent->e_id - 1];
3270Sstevel@tonic-gate 				_dirtbl->cd_file =
328*1976Sab196087 				    CAST_PTRINT(Word, ((char *)filetbl- addr));
3290Sstevel@tonic-gate 				_dirtbl->cd_obj =
330*1976Sab196087 				    CAST_PTRINT(Word, ((char *)objtbl - addr));
3310Sstevel@tonic-gate 
3320Sstevel@tonic-gate 				/* LINTED */
3330Sstevel@tonic-gate 				filetbl = (Rtc_file *)((char *)filetbl +
3340Sstevel@tonic-gate 				    ((ent->e_cnt + 1) * sizeof (Rtc_file)));
3350Sstevel@tonic-gate 
3360Sstevel@tonic-gate 				/*
3370Sstevel@tonic-gate 				 * Add this object to the hash table.
3380Sstevel@tonic-gate 				 */
3390Sstevel@tonic-gate 				hashval = ent->e_hash % hashbkts;
3400Sstevel@tonic-gate 				hashchn[ndx] = hashbkt[hashval];
3410Sstevel@tonic-gate 				hashbkt[hashval] = ndx++;
3420Sstevel@tonic-gate 
3430Sstevel@tonic-gate 				/*
3440Sstevel@tonic-gate 				 * Increment Rt_obj pointer (make sure pointer
3450Sstevel@tonic-gate 				 * falls on an 8-byte boundary).
3460Sstevel@tonic-gate 				 */
347*1976Sab196087 				objtbl = (Rtc_obj *)
348*1976Sab196087 					S_ROUND((uintptr_t)(objtbl + 1),
349*1976Sab196087 						sizeof (Lword));
3500Sstevel@tonic-gate 			}
3510Sstevel@tonic-gate 		}
3520Sstevel@tonic-gate 
3530Sstevel@tonic-gate 		/*
3540Sstevel@tonic-gate 		 * Now collect all pathnames.  These are typically full
3550Sstevel@tonic-gate 		 * pathnames, but may also be relative.  Simple filenames are
3560Sstevel@tonic-gate 		 * recorded as offsets into these pathnames, thus we need to
3570Sstevel@tonic-gate 		 * establish the new pathname first.
3580Sstevel@tonic-gate 		 */
3590Sstevel@tonic-gate 		for (bkt = 0; bkt < stbl->t_size; bkt++) {
3600Sstevel@tonic-gate 			for (ent = stbl->t_entry[bkt]; ent; ent = ent->e_next) {
3610Sstevel@tonic-gate 				Word		hashval;
3620Sstevel@tonic-gate 				Hash_obj	*obj = ent->e_obj;
3630Sstevel@tonic-gate 				char		*file = (char *)ent->e_key;
3640Sstevel@tonic-gate 				char		*_str;
3650Sstevel@tonic-gate 				Rtc_dir		*_dirtbl;
3660Sstevel@tonic-gate 				Rtc_file	*_filetbl;
3670Sstevel@tonic-gate 				int		_id;
3680Sstevel@tonic-gate 
3690Sstevel@tonic-gate 				/*
3700Sstevel@tonic-gate 				 * Skip empty and directory entries, and any
3710Sstevel@tonic-gate 				 * simple filename entries.
3720Sstevel@tonic-gate 				 */
3730Sstevel@tonic-gate 				if ((obj == 0) ||
3740Sstevel@tonic-gate 				    (obj->o_flags & RTC_OBJ_DIRENT) ||
3750Sstevel@tonic-gate 				    (ent->e_off))
3760Sstevel@tonic-gate 					continue;
3770Sstevel@tonic-gate 
3780Sstevel@tonic-gate 				/*
3790Sstevel@tonic-gate 				 * Assign basic object attributes.
3800Sstevel@tonic-gate 				 */
3810Sstevel@tonic-gate 				objtbl->co_hash = ent->e_hash;
3820Sstevel@tonic-gate 				objtbl->co_id = ent->e_id;
3830Sstevel@tonic-gate 				objtbl->co_flags = obj->o_flags | ent->e_flags;
3840Sstevel@tonic-gate 				objtbl->co_info = obj->o_info;
3850Sstevel@tonic-gate 
3860Sstevel@tonic-gate 				ent->e_cobj = objtbl;
3870Sstevel@tonic-gate 
3880Sstevel@tonic-gate 				/*
3890Sstevel@tonic-gate 				 * Assign the file name (from its key),
3900Sstevel@tonic-gate 				 * and copy its name to the string table.
3910Sstevel@tonic-gate 				 */
3920Sstevel@tonic-gate 				objtbl->co_name = (Addr)(_strtbl - strtbl);
3930Sstevel@tonic-gate 				(void) strcpy(_strtbl, file);
3940Sstevel@tonic-gate 				_strtbl += strlen(file) + 1;
3950Sstevel@tonic-gate 
3960Sstevel@tonic-gate 				/*
3970Sstevel@tonic-gate 				 * Add this file to its associated directory.
3980Sstevel@tonic-gate 				 */
3990Sstevel@tonic-gate 				_dirtbl = &dirtbl[ent->e_id - 1];
4000Sstevel@tonic-gate 				/* LINTED */
4010Sstevel@tonic-gate 				_filetbl = (Rtc_file *)
402*1976Sab196087 				    (CAST_PTRINT(char *, _dirtbl->cd_file)
403*1976Sab196087 					+ addr);
4040Sstevel@tonic-gate 
4050Sstevel@tonic-gate 				_id = --ent->e_dir->e_cnt;
4060Sstevel@tonic-gate 				_filetbl[_id].cf_obj =
407*1976Sab196087 				    CAST_PTRINT(Word, ((char *)objtbl - addr));
4080Sstevel@tonic-gate 
4090Sstevel@tonic-gate 				/*
4100Sstevel@tonic-gate 				 * If object has an alternative, record it in
4110Sstevel@tonic-gate 				 * the string table and assign the alternate
4120Sstevel@tonic-gate 				 * pointer.  The new alternative offset is
4130Sstevel@tonic-gate 				 * retained for reuse in other filename entries.
4140Sstevel@tonic-gate 				 */
4150Sstevel@tonic-gate 				if ((objtbl->co_flags & RTC_OBJ_ALTER) &&
4160Sstevel@tonic-gate 				    (obj->o_calter == 0)) {
4170Sstevel@tonic-gate 					_str = obj->o_alter;
4180Sstevel@tonic-gate 					objtbl->co_alter = obj->o_calter =
4190Sstevel@tonic-gate 					    (Addr)(_strtbl - strtbl);
4200Sstevel@tonic-gate 					(void) strcpy(_strtbl, _str);
4210Sstevel@tonic-gate 					_strtbl += strlen(_str) + 1;
4220Sstevel@tonic-gate 				} else
4230Sstevel@tonic-gate 					objtbl->co_alter = obj->o_calter;
4240Sstevel@tonic-gate 
4250Sstevel@tonic-gate 				/*
4260Sstevel@tonic-gate 				 * If object identifies the specific application
4270Sstevel@tonic-gate 				 * for which this cache is relevant, record it
4280Sstevel@tonic-gate 				 * in the header.
4290Sstevel@tonic-gate 				 */
4300Sstevel@tonic-gate 				if ((objtbl->co_flags &
4310Sstevel@tonic-gate 				    (RTC_OBJ_APP | RTC_OBJ_REALPTH)) ==
4320Sstevel@tonic-gate 				    (RTC_OBJ_APP | RTC_OBJ_REALPTH))
4330Sstevel@tonic-gate 					head->ch_app = _filetbl[_id].cf_obj;
4340Sstevel@tonic-gate 
4350Sstevel@tonic-gate 				/*
4360Sstevel@tonic-gate 				 * Add this object to the hash table.
4370Sstevel@tonic-gate 				 */
4380Sstevel@tonic-gate 				hashval = ent->e_hash % hashbkts;
4390Sstevel@tonic-gate 				hashchn[ndx] = hashbkt[hashval];
4400Sstevel@tonic-gate 				hashbkt[hashval] = ndx++;
4410Sstevel@tonic-gate 
4420Sstevel@tonic-gate 				/*
4430Sstevel@tonic-gate 				 * Increment Rt_obj pointer (make sure pointer
4440Sstevel@tonic-gate 				 * falls on an 8-byte boundary).
4450Sstevel@tonic-gate 				 */
446*1976Sab196087 				objtbl = (Rtc_obj *)
447*1976Sab196087 				    S_ROUND((uintptr_t)(objtbl + 1),
4480Sstevel@tonic-gate 				    sizeof (Lword));
4490Sstevel@tonic-gate 			}
4500Sstevel@tonic-gate 		}
4510Sstevel@tonic-gate 
4520Sstevel@tonic-gate 		/*
4530Sstevel@tonic-gate 		 * Finally pick off any simple filenames.
4540Sstevel@tonic-gate 		 */
4550Sstevel@tonic-gate 		for (bkt = 0; bkt < stbl->t_size; bkt++) {
4560Sstevel@tonic-gate 			for (ent = stbl->t_entry[bkt]; ent; ent = ent->e_next) {
4570Sstevel@tonic-gate 				Word		hashval;
4580Sstevel@tonic-gate 				Hash_obj *	obj = ent->e_obj;
4590Sstevel@tonic-gate 				Rtc_dir *	_dirtbl;
4600Sstevel@tonic-gate 				Rtc_file *	_filetbl;
4610Sstevel@tonic-gate 				int		_id;
4620Sstevel@tonic-gate 
4630Sstevel@tonic-gate 				/*
4640Sstevel@tonic-gate 				 * Skip everything except simple filenames.
4650Sstevel@tonic-gate 				 */
4660Sstevel@tonic-gate 				if (ent->e_off == 0)
4670Sstevel@tonic-gate 					continue;
4680Sstevel@tonic-gate 
4690Sstevel@tonic-gate 				/*
4700Sstevel@tonic-gate 				 * Assign basic object attributes.
4710Sstevel@tonic-gate 				 */
4720Sstevel@tonic-gate 				objtbl->co_hash = ent->e_hash;
4730Sstevel@tonic-gate 				objtbl->co_id = ent->e_id;
4740Sstevel@tonic-gate 				objtbl->co_flags = obj->o_flags | ent->e_flags;
4750Sstevel@tonic-gate 				objtbl->co_info = obj->o_info;
4760Sstevel@tonic-gate 				objtbl->co_alter = obj->o_calter;
4770Sstevel@tonic-gate 
4780Sstevel@tonic-gate 				ent->e_cobj = objtbl;
4790Sstevel@tonic-gate 
4800Sstevel@tonic-gate 				/*
4810Sstevel@tonic-gate 				 * Assign the file name from its full name.
4820Sstevel@tonic-gate 				 */
483*1976Sab196087 				objtbl->co_name = (Addr)(CAST_PTRINT(char *,
484*1976Sab196087 				    ent->e_path->e_cobj->co_name) + ent->e_off);
4850Sstevel@tonic-gate 
4860Sstevel@tonic-gate 				/*
4870Sstevel@tonic-gate 				 * Add this file to its associated directory.
4880Sstevel@tonic-gate 				 */
4890Sstevel@tonic-gate 				_dirtbl = &dirtbl[ent->e_id - 1];
4900Sstevel@tonic-gate 				/* LINTED */
4910Sstevel@tonic-gate 				_filetbl = (Rtc_file *)
492*1976Sab196087 				    (CAST_PTRINT(char *, _dirtbl->cd_file) +
493*1976Sab196087 				    addr);
4940Sstevel@tonic-gate 
4950Sstevel@tonic-gate 				_id = --ent->e_dir->e_cnt;
4960Sstevel@tonic-gate 				_filetbl[_id].cf_obj =
497*1976Sab196087 				    CAST_PTRINT(Word, ((char *)objtbl - addr));
4980Sstevel@tonic-gate 
4990Sstevel@tonic-gate 				/*
5000Sstevel@tonic-gate 				 * Add this object to the hash table.
5010Sstevel@tonic-gate 				 */
5020Sstevel@tonic-gate 				hashval = ent->e_hash % hashbkts;
5030Sstevel@tonic-gate 				hashchn[ndx] = hashbkt[hashval];
5040Sstevel@tonic-gate 				hashbkt[hashval] = ndx++;
5050Sstevel@tonic-gate 
5060Sstevel@tonic-gate 				/*
5070Sstevel@tonic-gate 				 * Increment Rt_obj pointer (make sure pointer
5080Sstevel@tonic-gate 				 * falls on an 8-byte boundary).
5090Sstevel@tonic-gate 				 */
510*1976Sab196087 				objtbl = (Rtc_obj *)
511*1976Sab196087 				    S_ROUND((uintptr_t)(objtbl + 1),
5120Sstevel@tonic-gate 				    sizeof (Lword));
5130Sstevel@tonic-gate 			}
5140Sstevel@tonic-gate 		}
5150Sstevel@tonic-gate 	}
5160Sstevel@tonic-gate 
5170Sstevel@tonic-gate 	/*
5180Sstevel@tonic-gate 	 * Add any library, or secure path definitions.
5190Sstevel@tonic-gate 	 */
5200Sstevel@tonic-gate 	if (crle->c_edlibpath) {
5210Sstevel@tonic-gate 		head->ch_edlibpath = head->ch_str + (_strtbl - strtbl);
5220Sstevel@tonic-gate 
5230Sstevel@tonic-gate 		(void) strcpy(_strtbl, crle->c_edlibpath);
5240Sstevel@tonic-gate 		_strtbl += strlen((char *)crle->c_edlibpath) + 1;
5250Sstevel@tonic-gate 	} else
5260Sstevel@tonic-gate 		head->ch_edlibpath = 0;
5270Sstevel@tonic-gate 
5280Sstevel@tonic-gate 	if (crle->c_adlibpath) {
5290Sstevel@tonic-gate 		head->ch_adlibpath = head->ch_str + (_strtbl - strtbl);
5300Sstevel@tonic-gate 
5310Sstevel@tonic-gate 		(void) strcpy(_strtbl, crle->c_adlibpath);
5320Sstevel@tonic-gate 		_strtbl += strlen((char *)crle->c_adlibpath) + 1;
5330Sstevel@tonic-gate 	} else
5340Sstevel@tonic-gate 		head->ch_adlibpath = 0;
5350Sstevel@tonic-gate 
5360Sstevel@tonic-gate 	if (crle->c_eslibpath) {
5370Sstevel@tonic-gate 		head->ch_eslibpath = head->ch_str + (_strtbl - strtbl);
5380Sstevel@tonic-gate 
5390Sstevel@tonic-gate 		(void) strcpy(_strtbl, crle->c_eslibpath);
5400Sstevel@tonic-gate 		_strtbl += strlen((char *)crle->c_eslibpath) + 1;
5410Sstevel@tonic-gate 	} else
5420Sstevel@tonic-gate 		head->ch_eslibpath = 0;
5430Sstevel@tonic-gate 
5440Sstevel@tonic-gate 	if (crle->c_aslibpath) {
5450Sstevel@tonic-gate 		head->ch_aslibpath = head->ch_str + (_strtbl - strtbl);
5460Sstevel@tonic-gate 
5470Sstevel@tonic-gate 		(void) strcpy(_strtbl, crle->c_aslibpath);
5480Sstevel@tonic-gate 		_strtbl += strlen((char *)crle->c_aslibpath) + 1;
5490Sstevel@tonic-gate 	} else
5500Sstevel@tonic-gate 		head->ch_aslibpath = 0;
5510Sstevel@tonic-gate 
5520Sstevel@tonic-gate 	/*
5530Sstevel@tonic-gate 	 * Add any environment variable entries.
5540Sstevel@tonic-gate 	 */
5550Sstevel@tonic-gate 	if (crle->c_envnum) {
5560Sstevel@tonic-gate 		Env_desc *	env;
5570Sstevel@tonic-gate 		Listnode *	lnp;
5580Sstevel@tonic-gate 
5590Sstevel@tonic-gate 		for (LIST_TRAVERSE(&(crle->c_env), lnp, env)) {
5600Sstevel@tonic-gate 			envtbl->env_str = head->ch_str + (_strtbl - strtbl);
5610Sstevel@tonic-gate 			envtbl->env_flags = env->e_flags;
5620Sstevel@tonic-gate 
5630Sstevel@tonic-gate 			(void) strcpy(_strtbl, env->e_str);
5640Sstevel@tonic-gate 			_strtbl += env->e_totsz;
5650Sstevel@tonic-gate 
5660Sstevel@tonic-gate 			envtbl++;
5670Sstevel@tonic-gate 		}
5680Sstevel@tonic-gate 		envtbl->env_str = 0;
5690Sstevel@tonic-gate 		envtbl->env_flags = 0;
5700Sstevel@tonic-gate 	}
5710Sstevel@tonic-gate 
5720Sstevel@tonic-gate 	/*
5730Sstevel@tonic-gate 	 * Add any filter/filtee association entries.
5740Sstevel@tonic-gate 	 */
5750Sstevel@tonic-gate 	if (crle->c_fltrnum) {
5760Sstevel@tonic-gate 		Flt_desc *	flt;
5770Sstevel@tonic-gate 		Listnode *	lnp1;
5780Sstevel@tonic-gate 
5790Sstevel@tonic-gate 		for (LIST_TRAVERSE(&(crle->c_flt), lnp1, flt)) {
5800Sstevel@tonic-gate 			Hash_ent *	flte;
5810Sstevel@tonic-gate 			Listnode *	lnp2;
5820Sstevel@tonic-gate 
5830Sstevel@tonic-gate 			/*
5840Sstevel@tonic-gate 			 * Establish the filter name, and filtee string, as
5850Sstevel@tonic-gate 			 * offsets into the configuration files string table.
5860Sstevel@tonic-gate 			 * Establish the filtee as the offset into the filtee
5870Sstevel@tonic-gate 			 * table.
5880Sstevel@tonic-gate 			 */
5890Sstevel@tonic-gate 			fltrtbl->fr_filter = flt->f_fent->e_cobj->co_name;
5900Sstevel@tonic-gate 			fltrtbl->fr_string = _strtbl - strtbl;
5910Sstevel@tonic-gate 			(void) strcpy(_strtbl, flt->f_str);
5920Sstevel@tonic-gate 			_strtbl += flt->f_strsz;
593*1976Sab196087 			fltrtbl->fr_filtee = (Word)
594*1976Sab196087 			    ((uintptr_t)_fltetbl - (uintptr_t)fltetbl);
5950Sstevel@tonic-gate 
5960Sstevel@tonic-gate 			for (LIST_TRAVERSE(&(flt->f_filtee), lnp2, flte)) {
5970Sstevel@tonic-gate 				/*
5980Sstevel@tonic-gate 				 * Establish the filtee name as the offset into
5990Sstevel@tonic-gate 				 * the configuration files string table.
6000Sstevel@tonic-gate 				 */
6010Sstevel@tonic-gate 				_fltetbl->fe_filtee = flte->e_cobj->co_name;
6020Sstevel@tonic-gate 				_fltetbl++;
6030Sstevel@tonic-gate 			}
6040Sstevel@tonic-gate 			_fltetbl->fe_filtee = 0;
6050Sstevel@tonic-gate 			_fltetbl++, fltrtbl++;
6060Sstevel@tonic-gate 		}
6070Sstevel@tonic-gate 		fltrtbl->fr_filter = 0;
6080Sstevel@tonic-gate 		fltrtbl->fr_filtee = 0;
6090Sstevel@tonic-gate 	}
6100Sstevel@tonic-gate 
6110Sstevel@tonic-gate 	/*
6120Sstevel@tonic-gate 	 * Flush everything out.
6130Sstevel@tonic-gate 	 */
6140Sstevel@tonic-gate 	(void) close(crle->c_tempfd);
615*1976Sab196087 	if (msync((void *)crle->c_tempaddr, crle->c_tempsize, MS_ASYNC) == -1) {
6160Sstevel@tonic-gate 		int err = errno;
6170Sstevel@tonic-gate 		(void) fprintf(stderr, MSG_INTL(MSG_SYS_TRUNC),
6180Sstevel@tonic-gate 		    crle->c_name, crle->c_tempname, strerror(err));
6190Sstevel@tonic-gate 		return (1);
6200Sstevel@tonic-gate 	}
6210Sstevel@tonic-gate 
6220Sstevel@tonic-gate 	return (0);
6230Sstevel@tonic-gate }
6240Sstevel@tonic-gate 
6250Sstevel@tonic-gate /*
6260Sstevel@tonic-gate  * Update a configuration file.  If dldump()'ed images have been created then
6270Sstevel@tonic-gate  * the memory reservation of those images is added to the configuration file.
6280Sstevel@tonic-gate  * The temporary file is then moved into its final resting place.
6290Sstevel@tonic-gate  */
630238Sseizo int
6310Sstevel@tonic-gate updateconfig(Crle_desc * crle)
6320Sstevel@tonic-gate {
633*1976Sab196087 	Rtc_head *head = (Rtc_head *)crle->c_tempheadaddr;
6340Sstevel@tonic-gate 
6350Sstevel@tonic-gate 	if (crle->c_flags & CRLE_DUMP) {
6360Sstevel@tonic-gate 		head->ch_cnflags &= ~RTC_HDR_IGNORE;
6370Sstevel@tonic-gate 
6380Sstevel@tonic-gate 		if (msync((void *)crle->c_tempaddr, crle->c_tempsize,
6390Sstevel@tonic-gate 		    MS_ASYNC) == -1) {
6400Sstevel@tonic-gate 			int err = errno;
6410Sstevel@tonic-gate 			(void) fprintf(stderr, MSG_INTL(MSG_SYS_TRUNC),
6420Sstevel@tonic-gate 			    crle->c_name, crle->c_tempname, strerror(err));
6430Sstevel@tonic-gate 			return (1);
6440Sstevel@tonic-gate 		}
6450Sstevel@tonic-gate 	}
6460Sstevel@tonic-gate 
6470Sstevel@tonic-gate 	/*
6480Sstevel@tonic-gate 	 * If an original configuration file exists, remove it.
6490Sstevel@tonic-gate 	 */
6500Sstevel@tonic-gate 	if (crle->c_flags & CRLE_EXISTS)
6510Sstevel@tonic-gate 		(void) unlink(crle->c_confil);
6520Sstevel@tonic-gate 
6530Sstevel@tonic-gate 	/*
6540Sstevel@tonic-gate 	 * Move the config file to its final resting place.  If the two files
6550Sstevel@tonic-gate 	 * exist on the same filesystem a rename is sufficient.
6560Sstevel@tonic-gate 	 */
6570Sstevel@tonic-gate 	if (crle->c_flags & CRLE_DIFFDEV) {
6580Sstevel@tonic-gate 		int	fd;
6590Sstevel@tonic-gate 
6600Sstevel@tonic-gate 		if ((fd = open(crle->c_confil, (O_RDWR | O_CREAT | O_TRUNC),
6610Sstevel@tonic-gate 		    0666)) == -1) {
6620Sstevel@tonic-gate 			int err = errno;
6630Sstevel@tonic-gate 			(void) fprintf(stderr, MSG_INTL(MSG_SYS_OPEN),
6640Sstevel@tonic-gate 			    crle->c_name, crle->c_confil, strerror(err));
6650Sstevel@tonic-gate 			return (1);
6660Sstevel@tonic-gate 		}
6670Sstevel@tonic-gate 		if (write(fd, (void *)crle->c_tempaddr, crle->c_tempsize) !=
6680Sstevel@tonic-gate 		    crle->c_tempsize) {
6690Sstevel@tonic-gate 			int err = errno;
6700Sstevel@tonic-gate 			(void) fprintf(stderr, MSG_INTL(MSG_SYS_WRITE),
6710Sstevel@tonic-gate 			    crle->c_name, crle->c_confil, strerror(err));
6720Sstevel@tonic-gate 			return (1);
6730Sstevel@tonic-gate 		}
6740Sstevel@tonic-gate 		(void) close(fd);
6750Sstevel@tonic-gate 		(void) unlink(crle->c_tempname);
6760Sstevel@tonic-gate 	} else
6770Sstevel@tonic-gate 		(void) rename(crle->c_tempname, crle->c_confil);
6780Sstevel@tonic-gate 
6790Sstevel@tonic-gate 	return (0);
6800Sstevel@tonic-gate }
681