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
51976Sab196087 * Common Development and Distribution License (the "License").
61976Sab196087 * 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*9131SRod.Evans@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
230Sstevel@tonic-gate * Use is subject to license terms.
240Sstevel@tonic-gate */
250Sstevel@tonic-gate
260Sstevel@tonic-gate #include <sys/mman.h>
270Sstevel@tonic-gate #include <sys/types.h>
280Sstevel@tonic-gate #include <fcntl.h>
290Sstevel@tonic-gate #include <unistd.h>
300Sstevel@tonic-gate #include <errno.h>
310Sstevel@tonic-gate #include <stdio.h>
320Sstevel@tonic-gate #include <string.h>
330Sstevel@tonic-gate #include "rtc.h"
340Sstevel@tonic-gate #include "_crle.h"
350Sstevel@tonic-gate #include "msg.h"
360Sstevel@tonic-gate
370Sstevel@tonic-gate
380Sstevel@tonic-gate #define MAXNBKTS 10007
390Sstevel@tonic-gate
400Sstevel@tonic-gate static const int hashsize[] = {
410Sstevel@tonic-gate 3, 7, 13, 31, 53, 67, 83, 97,
420Sstevel@tonic-gate 101, 151, 211, 251, 307, 353, 401, 457, 503,
430Sstevel@tonic-gate 557, 601, 653, 701, 751, 809, 859, 907, 953,
440Sstevel@tonic-gate 1009, 1103, 1201, 1301, 1409, 1511, 1601, 1709, 1801,
450Sstevel@tonic-gate 1901, 2003, 2111, 2203, 2309, 2411, 2503, 2609, 2707,
460Sstevel@tonic-gate 2801, 2903, 3001, 3109, 3203, 3301, 3407, 3511, 3607,
470Sstevel@tonic-gate 3701, 3803, 3907, 4001, 5003, 6101, 7001, 8101, 9001,
480Sstevel@tonic-gate MAXNBKTS
490Sstevel@tonic-gate };
500Sstevel@tonic-gate
510Sstevel@tonic-gate /*
520Sstevel@tonic-gate * Generate a configuration file from the internal configuration information.
530Sstevel@tonic-gate * (very link-editor like).
540Sstevel@tonic-gate */
55238Sseizo int
genconfig(Crle_desc * crle)56*9131SRod.Evans@Sun.COM genconfig(Crle_desc *crle)
570Sstevel@tonic-gate {
580Sstevel@tonic-gate int ndx, bkt;
590Sstevel@tonic-gate size_t size, hashoff = 0, stroff = 0, objoff = 0;
600Sstevel@tonic-gate size_t diroff = 0, fileoff = 0, envoff = 0;
610Sstevel@tonic-gate size_t fltroff = 0, flteoff = 0;
620Sstevel@tonic-gate Addr addr;
631976Sab196087 Rtc_id *id;
640Sstevel@tonic-gate Rtc_head *head;
65*9131SRod.Evans@Sun.COM Word *hashtbl, *hashbkt, *hashchn, hashbkts = 0;
660Sstevel@tonic-gate char *strtbl, *_strtbl;
670Sstevel@tonic-gate Rtc_obj *objtbl;
680Sstevel@tonic-gate Rtc_dir *dirtbl;
690Sstevel@tonic-gate Rtc_file *filetbl;
700Sstevel@tonic-gate Rtc_env *envtbl;
710Sstevel@tonic-gate Rtc_fltr *fltrtbl;
720Sstevel@tonic-gate Rtc_flte *fltetbl, * _fltetbl;
730Sstevel@tonic-gate Hash_tbl *stbl = crle->c_strtbl;
740Sstevel@tonic-gate Hash_ent *ent;
750Sstevel@tonic-gate
760Sstevel@tonic-gate /*
770Sstevel@tonic-gate * Establish the size of the configuration file.
780Sstevel@tonic-gate */
790Sstevel@tonic-gate size = S_ROUND(sizeof (Rtc_head), sizeof (Word));
800Sstevel@tonic-gate
810Sstevel@tonic-gate if (crle->c_hashstrnum) {
820Sstevel@tonic-gate hashoff = size;
830Sstevel@tonic-gate
840Sstevel@tonic-gate /*
850Sstevel@tonic-gate * Increment the hash string number to account for an initial
860Sstevel@tonic-gate * null entry. Indexes start at 1 to simplify hash lookup.
870Sstevel@tonic-gate */
880Sstevel@tonic-gate crle->c_hashstrnum++;
890Sstevel@tonic-gate
900Sstevel@tonic-gate /*
910Sstevel@tonic-gate * Determine the hash table size. Establish the number of
920Sstevel@tonic-gate * buckets from the number of strings, the number of chains is
930Sstevel@tonic-gate * equivalent to the number of objects, and two entries for the
940Sstevel@tonic-gate * nbucket and nchain entries.
950Sstevel@tonic-gate */
960Sstevel@tonic-gate for (ndx = 0; ndx < (sizeof (hashsize) / sizeof (int)); ndx++) {
970Sstevel@tonic-gate if (crle->c_hashstrnum > hashsize[ndx])
980Sstevel@tonic-gate continue;
990Sstevel@tonic-gate hashbkts = hashsize[ndx];
1000Sstevel@tonic-gate break;
1010Sstevel@tonic-gate }
1020Sstevel@tonic-gate if (hashbkts == 0)
1030Sstevel@tonic-gate hashbkts = MAXNBKTS;
1040Sstevel@tonic-gate size += ((2 + hashbkts + crle->c_hashstrnum) * sizeof (Word));
1050Sstevel@tonic-gate size = S_ROUND(size, sizeof (Lword));
1060Sstevel@tonic-gate objoff = size;
1070Sstevel@tonic-gate
1080Sstevel@tonic-gate /*
1090Sstevel@tonic-gate * Add the object table size (account for an 8-byte alignment
1100Sstevel@tonic-gate * requirement for each object).
1110Sstevel@tonic-gate */
1120Sstevel@tonic-gate size += (crle->c_hashstrnum *
1130Sstevel@tonic-gate S_ROUND(sizeof (Rtc_obj), sizeof (Lword)));
1140Sstevel@tonic-gate
1150Sstevel@tonic-gate /*
1160Sstevel@tonic-gate * Add the file descriptor arrays.
1170Sstevel@tonic-gate */
1180Sstevel@tonic-gate fileoff = size;
1190Sstevel@tonic-gate size += S_ROUND((crle->c_filenum * sizeof (Rtc_file)),
1200Sstevel@tonic-gate sizeof (Word));
1210Sstevel@tonic-gate
1220Sstevel@tonic-gate /*
1230Sstevel@tonic-gate * Add the directory descriptor array.
1240Sstevel@tonic-gate */
1250Sstevel@tonic-gate diroff = size;
1260Sstevel@tonic-gate size += S_ROUND((crle->c_dirnum * sizeof (Rtc_dir)),
1270Sstevel@tonic-gate sizeof (Word));
1280Sstevel@tonic-gate }
1290Sstevel@tonic-gate
1300Sstevel@tonic-gate /*
1310Sstevel@tonic-gate * Add any environment string array (insure zero last entry).
1320Sstevel@tonic-gate */
1330Sstevel@tonic-gate if (crle->c_envnum) {
1340Sstevel@tonic-gate envoff = size;
1350Sstevel@tonic-gate size += S_ROUND(((crle->c_envnum + 1) * sizeof (Rtc_env)),
1360Sstevel@tonic-gate sizeof (Word));
1370Sstevel@tonic-gate }
1380Sstevel@tonic-gate
1390Sstevel@tonic-gate /*
1400Sstevel@tonic-gate * Add any filter/filtee association arrays (insure zero last entry for
1410Sstevel@tonic-gate * the filter array, the filtee arrays are already accounted for).
1420Sstevel@tonic-gate */
1430Sstevel@tonic-gate if (crle->c_fltrnum) {
1440Sstevel@tonic-gate fltroff = size;
1450Sstevel@tonic-gate size += S_ROUND(((crle->c_fltrnum + 1) * sizeof (Rtc_fltr)),
1460Sstevel@tonic-gate sizeof (Word));
1470Sstevel@tonic-gate flteoff = size;
1480Sstevel@tonic-gate size += S_ROUND((crle->c_fltenum * sizeof (Rtc_flte)),
1490Sstevel@tonic-gate sizeof (Word));
1500Sstevel@tonic-gate }
1510Sstevel@tonic-gate
1520Sstevel@tonic-gate /*
1530Sstevel@tonic-gate * Add the string table size (this may contain library and/or secure
1540Sstevel@tonic-gate * path strings, in addition to any directory/file strings).
1550Sstevel@tonic-gate */
1560Sstevel@tonic-gate if (crle->c_strsize) {
1570Sstevel@tonic-gate stroff = size;
1580Sstevel@tonic-gate size += S_ROUND(crle->c_strsize, sizeof (Word));
1590Sstevel@tonic-gate }
1600Sstevel@tonic-gate
1611976Sab196087 /* Account for addition of Rtc_id block at the start */
1621976Sab196087 if (crle->c_flags & CRLE_ADDID)
1631976Sab196087 size += sizeof (Rtc_id);
1641976Sab196087
1650Sstevel@tonic-gate /*
1660Sstevel@tonic-gate * Truncate our temporary file now that we know its size and map it.
1670Sstevel@tonic-gate */
1680Sstevel@tonic-gate if (ftruncate(crle->c_tempfd, size) == -1) {
1690Sstevel@tonic-gate int err = errno;
1700Sstevel@tonic-gate (void) fprintf(stderr, MSG_INTL(MSG_SYS_TRUNC),
1710Sstevel@tonic-gate crle->c_name, crle->c_tempname, strerror(err));
1720Sstevel@tonic-gate (void) close(crle->c_tempfd);
1730Sstevel@tonic-gate return (1);
1740Sstevel@tonic-gate }
1750Sstevel@tonic-gate if ((addr = (Addr)mmap(0, size, (PROT_READ | PROT_WRITE), MAP_SHARED,
1760Sstevel@tonic-gate crle->c_tempfd, 0)) == (Addr)-1) {
1770Sstevel@tonic-gate int err = errno;
1780Sstevel@tonic-gate (void) fprintf(stderr, MSG_INTL(MSG_SYS_MMAP),
1790Sstevel@tonic-gate crle->c_name, crle->c_tempname, strerror(err));
1800Sstevel@tonic-gate (void) close(crle->c_tempfd);
1810Sstevel@tonic-gate return (1);
1820Sstevel@tonic-gate }
1830Sstevel@tonic-gate
1840Sstevel@tonic-gate /*
1850Sstevel@tonic-gate * Save the mapped files info for possible dldump(3dl) updates.
1860Sstevel@tonic-gate */
1870Sstevel@tonic-gate crle->c_tempaddr = addr;
1880Sstevel@tonic-gate crle->c_tempsize = size;
1890Sstevel@tonic-gate
1900Sstevel@tonic-gate /*
1911976Sab196087 * Rtc_id goes at the top, followed by the Rtc_head. We base
1921976Sab196087 * all offset calculations relative to Rtc_head, not from
1931976Sab196087 * the top of the file. This eases backwards compatability to
1941976Sab196087 * older versons that lacked the Rtc_id at the top.
1950Sstevel@tonic-gate */
1961976Sab196087 if (crle->c_flags & CRLE_ADDID) {
1971976Sab196087 /* The contents of the Rtc_id are all known at compile time */
1981976Sab196087 static const Rtc_id id_template = {
1991976Sab196087 RTC_ID_MAG0, RTC_ID_MAG1, RTC_ID_MAG2, RTC_ID_MAG3,
2001976Sab196087 M_CLASS, M_DATA, M_MACH,
2011976Sab196087 { 0, 0, 0, 0, 0, 0, 0, 0, 0 } };
2021976Sab196087
2031976Sab196087 id = (Rtc_id *) addr;
2041976Sab196087 *id = id_template; /* Fill in the Rtc_id data */
2051976Sab196087 addr += sizeof (Rtc_id);
2061976Sab196087 } else {
2071976Sab196087 id = NULL;
2081976Sab196087 }
2091976Sab196087 crle->c_tempheadaddr = addr;
2100Sstevel@tonic-gate head = (Rtc_head *)addr;
2110Sstevel@tonic-gate
2121976Sab196087 /*
2131976Sab196087 * Establish the real address of each of the structures within the file.
2141976Sab196087 */
2150Sstevel@tonic-gate head->ch_hash = hashoff;
2160Sstevel@tonic-gate /* LINTED */
2171976Sab196087 hashtbl = (Word *)(CAST_PTRINT(char *, head->ch_hash) + addr);
2180Sstevel@tonic-gate
2190Sstevel@tonic-gate head->ch_obj = objoff;
2200Sstevel@tonic-gate /* LINTED */
2211976Sab196087 objtbl = (Rtc_obj *)(CAST_PTRINT(char *, head->ch_obj) + addr);
2221976Sab196087 objtbl = (Rtc_obj *)S_ROUND((uintptr_t)(objtbl + 1), sizeof (Lword));
2230Sstevel@tonic-gate
2240Sstevel@tonic-gate head->ch_file = fileoff;
2250Sstevel@tonic-gate /* LINTED */
2261976Sab196087 filetbl = (Rtc_file *)(CAST_PTRINT(char *, head->ch_file) + addr);
2270Sstevel@tonic-gate
2280Sstevel@tonic-gate head->ch_dir = diroff;
2290Sstevel@tonic-gate /* LINTED */
2301976Sab196087 dirtbl = (Rtc_dir *)(CAST_PTRINT(char *, head->ch_dir) + addr);
2310Sstevel@tonic-gate
2320Sstevel@tonic-gate head->ch_env = envoff;
2330Sstevel@tonic-gate /* LINTED */
2341976Sab196087 envtbl = (Rtc_env *)(CAST_PTRINT(char *, head->ch_env) + addr);
2350Sstevel@tonic-gate
2360Sstevel@tonic-gate head->ch_fltr = fltroff;
2370Sstevel@tonic-gate /* LINTED */
2381976Sab196087 fltrtbl = (Rtc_fltr *)(CAST_PTRINT(char *, head->ch_fltr) + addr);
2390Sstevel@tonic-gate head->ch_flte = flteoff;
2400Sstevel@tonic-gate /* LINTED */
241*9131SRod.Evans@Sun.COM fltetbl = _fltetbl = (Rtc_flte *)(CAST_PTRINT(char *, head->ch_flte) +
242*9131SRod.Evans@Sun.COM addr);
2430Sstevel@tonic-gate
2440Sstevel@tonic-gate head->ch_str = stroff;
2451976Sab196087 strtbl = _strtbl = (char *)(CAST_PTRINT(char *, head->ch_str) + addr);
2460Sstevel@tonic-gate
2470Sstevel@tonic-gate /*
2480Sstevel@tonic-gate * Fill in additional basic header information.
2490Sstevel@tonic-gate */
2500Sstevel@tonic-gate head->ch_version = RTC_VER_CURRENT;
2510Sstevel@tonic-gate
2520Sstevel@tonic-gate if (crle->c_flags & CRLE_ALTER)
2530Sstevel@tonic-gate head->ch_cnflags |= RTC_HDR_ALTER;
2540Sstevel@tonic-gate if (crle->c_flags & CRLE_DUMP) {
2550Sstevel@tonic-gate head->ch_cnflags |= RTC_HDR_IGNORE;
2560Sstevel@tonic-gate head->ch_dlflags = crle->c_dlflags;
2570Sstevel@tonic-gate }
2581976Sab196087 #ifdef _ELF64
2591976Sab196087 head->ch_cnflags |= RTC_HDR_64;
2601976Sab196087 #endif
2610Sstevel@tonic-gate
2620Sstevel@tonic-gate #ifndef SGS_PRE_UNIFIED_PROCESS
2630Sstevel@tonic-gate head->ch_cnflags |= RTC_HDR_UPM;
2640Sstevel@tonic-gate #endif
2650Sstevel@tonic-gate /*
2660Sstevel@tonic-gate * If we have a hash table then there are directory and file entries
2670Sstevel@tonic-gate * to process.
2680Sstevel@tonic-gate */
2690Sstevel@tonic-gate if (crle->c_hashstrnum) {
2700Sstevel@tonic-gate hashtbl[0] = hashbkts;
2710Sstevel@tonic-gate hashtbl[1] = crle->c_hashstrnum;
2720Sstevel@tonic-gate hashbkt = &hashtbl[2];
2730Sstevel@tonic-gate hashchn = &hashtbl[2 + hashbkts];
2740Sstevel@tonic-gate
2750Sstevel@tonic-gate /*
2760Sstevel@tonic-gate * Insure all hash chain and directory/filename table entries
2770Sstevel@tonic-gate * are cleared.
2780Sstevel@tonic-gate */
2790Sstevel@tonic-gate (void) memset(hashchn, 0, (crle->c_hashstrnum * sizeof (Word)));
2800Sstevel@tonic-gate (void) memset(dirtbl, 0, (strtbl - (char *)dirtbl));
2810Sstevel@tonic-gate
2820Sstevel@tonic-gate /*
2830Sstevel@tonic-gate * Loop through the current string table list inspecting only
2840Sstevel@tonic-gate * directories.
2850Sstevel@tonic-gate */
2860Sstevel@tonic-gate for (ndx = 1, bkt = 0; bkt < stbl->t_size; bkt++) {
2870Sstevel@tonic-gate for (ent = stbl->t_entry[bkt]; ent; ent = ent->e_next) {
2880Sstevel@tonic-gate Word hashval;
2890Sstevel@tonic-gate Hash_obj *obj = ent->e_obj;
2900Sstevel@tonic-gate char *dir = (char *)ent->e_key;
2910Sstevel@tonic-gate Rtc_dir *_dirtbl;
2920Sstevel@tonic-gate
2930Sstevel@tonic-gate /*
2940Sstevel@tonic-gate * Skip any empty and non-directory entries.
2950Sstevel@tonic-gate */
296*9131SRod.Evans@Sun.COM if ((obj == NULL) ||
2970Sstevel@tonic-gate ((obj->o_flags & RTC_OBJ_DIRENT) == 0))
2980Sstevel@tonic-gate continue;
2990Sstevel@tonic-gate
3000Sstevel@tonic-gate /*
3010Sstevel@tonic-gate * Assign basic object attributes.
3020Sstevel@tonic-gate */
3030Sstevel@tonic-gate objtbl->co_hash = ent->e_hash;
3040Sstevel@tonic-gate objtbl->co_id = ent->e_id;
3050Sstevel@tonic-gate objtbl->co_flags = obj->o_flags | ent->e_flags;
3060Sstevel@tonic-gate objtbl->co_info = obj->o_info;
3070Sstevel@tonic-gate
3080Sstevel@tonic-gate ent->e_cobj = objtbl;
3090Sstevel@tonic-gate
3100Sstevel@tonic-gate /*
3110Sstevel@tonic-gate * Assign the directory name (from its key),
3120Sstevel@tonic-gate * and copy its name to the string table.
3130Sstevel@tonic-gate */
3140Sstevel@tonic-gate objtbl->co_name = (Addr)(_strtbl - strtbl);
3150Sstevel@tonic-gate (void) strcpy(_strtbl, dir);
3160Sstevel@tonic-gate _strtbl += strlen(dir) + 1;
3170Sstevel@tonic-gate
3180Sstevel@tonic-gate /*
3190Sstevel@tonic-gate * Establish an entry in the directory table and
3200Sstevel@tonic-gate * reserve space for its associated filename
3210Sstevel@tonic-gate * entries (note, we add a trailing null file
3220Sstevel@tonic-gate * entry to simplify later inspection of the
3230Sstevel@tonic-gate * final configuration file.
3240Sstevel@tonic-gate */
3250Sstevel@tonic-gate _dirtbl = &dirtbl[ent->e_id - 1];
3260Sstevel@tonic-gate _dirtbl->cd_file =
3271976Sab196087 CAST_PTRINT(Word, ((char *)filetbl- addr));
3280Sstevel@tonic-gate _dirtbl->cd_obj =
3291976Sab196087 CAST_PTRINT(Word, ((char *)objtbl - addr));
3300Sstevel@tonic-gate
3310Sstevel@tonic-gate /* LINTED */
3320Sstevel@tonic-gate filetbl = (Rtc_file *)((char *)filetbl +
3330Sstevel@tonic-gate ((ent->e_cnt + 1) * sizeof (Rtc_file)));
3340Sstevel@tonic-gate
3350Sstevel@tonic-gate /*
3360Sstevel@tonic-gate * Add this object to the hash table.
3370Sstevel@tonic-gate */
3380Sstevel@tonic-gate hashval = ent->e_hash % hashbkts;
3390Sstevel@tonic-gate hashchn[ndx] = hashbkt[hashval];
3400Sstevel@tonic-gate hashbkt[hashval] = ndx++;
3410Sstevel@tonic-gate
3420Sstevel@tonic-gate /*
3430Sstevel@tonic-gate * Increment Rt_obj pointer (make sure pointer
3440Sstevel@tonic-gate * falls on an 8-byte boundary).
3450Sstevel@tonic-gate */
346*9131SRod.Evans@Sun.COM objtbl =
347*9131SRod.Evans@Sun.COM (Rtc_obj *)S_ROUND((uintptr_t)(objtbl + 1),
348*9131SRod.Evans@Sun.COM sizeof (Lword));
3490Sstevel@tonic-gate }
3500Sstevel@tonic-gate }
3510Sstevel@tonic-gate
3520Sstevel@tonic-gate /*
3530Sstevel@tonic-gate * Now collect all pathnames. These are typically full
3540Sstevel@tonic-gate * pathnames, but may also be relative. Simple filenames are
3550Sstevel@tonic-gate * recorded as offsets into these pathnames, thus we need to
3560Sstevel@tonic-gate * establish the new pathname first.
3570Sstevel@tonic-gate */
3580Sstevel@tonic-gate for (bkt = 0; bkt < stbl->t_size; bkt++) {
3590Sstevel@tonic-gate for (ent = stbl->t_entry[bkt]; ent; ent = ent->e_next) {
3600Sstevel@tonic-gate Word hashval;
3610Sstevel@tonic-gate Hash_obj *obj = ent->e_obj;
3620Sstevel@tonic-gate char *file = (char *)ent->e_key;
3630Sstevel@tonic-gate char *_str;
3640Sstevel@tonic-gate Rtc_dir *_dirtbl;
3650Sstevel@tonic-gate Rtc_file *_filetbl;
3660Sstevel@tonic-gate int _id;
3670Sstevel@tonic-gate
3680Sstevel@tonic-gate /*
3690Sstevel@tonic-gate * Skip empty and directory entries, and any
3700Sstevel@tonic-gate * simple filename entries.
3710Sstevel@tonic-gate */
372*9131SRod.Evans@Sun.COM if ((obj == NULL) ||
3730Sstevel@tonic-gate (obj->o_flags & RTC_OBJ_DIRENT) ||
3740Sstevel@tonic-gate (ent->e_off))
3750Sstevel@tonic-gate continue;
3760Sstevel@tonic-gate
3770Sstevel@tonic-gate /*
3780Sstevel@tonic-gate * Assign basic object attributes.
3790Sstevel@tonic-gate */
3800Sstevel@tonic-gate objtbl->co_hash = ent->e_hash;
3810Sstevel@tonic-gate objtbl->co_id = ent->e_id;
3820Sstevel@tonic-gate objtbl->co_flags = obj->o_flags | ent->e_flags;
3830Sstevel@tonic-gate objtbl->co_info = obj->o_info;
3840Sstevel@tonic-gate
3850Sstevel@tonic-gate ent->e_cobj = objtbl;
3860Sstevel@tonic-gate
3870Sstevel@tonic-gate /*
3880Sstevel@tonic-gate * Assign the file name (from its key),
3890Sstevel@tonic-gate * and copy its name to the string table.
3900Sstevel@tonic-gate */
3910Sstevel@tonic-gate objtbl->co_name = (Addr)(_strtbl - strtbl);
3920Sstevel@tonic-gate (void) strcpy(_strtbl, file);
3930Sstevel@tonic-gate _strtbl += strlen(file) + 1;
3940Sstevel@tonic-gate
3950Sstevel@tonic-gate /*
3960Sstevel@tonic-gate * Add this file to its associated directory.
3970Sstevel@tonic-gate */
3980Sstevel@tonic-gate _dirtbl = &dirtbl[ent->e_id - 1];
3990Sstevel@tonic-gate /* LINTED */
400*9131SRod.Evans@Sun.COM _filetbl = (Rtc_file *)(CAST_PTRINT(char *,
401*9131SRod.Evans@Sun.COM _dirtbl->cd_file) + addr);
4020Sstevel@tonic-gate
4030Sstevel@tonic-gate _id = --ent->e_dir->e_cnt;
4040Sstevel@tonic-gate _filetbl[_id].cf_obj =
4051976Sab196087 CAST_PTRINT(Word, ((char *)objtbl - addr));
4060Sstevel@tonic-gate
4070Sstevel@tonic-gate /*
4080Sstevel@tonic-gate * If object has an alternative, record it in
4090Sstevel@tonic-gate * the string table and assign the alternate
4100Sstevel@tonic-gate * pointer. The new alternative offset is
4110Sstevel@tonic-gate * retained for reuse in other filename entries.
4120Sstevel@tonic-gate */
4130Sstevel@tonic-gate if ((objtbl->co_flags & RTC_OBJ_ALTER) &&
4140Sstevel@tonic-gate (obj->o_calter == 0)) {
4150Sstevel@tonic-gate _str = obj->o_alter;
4160Sstevel@tonic-gate objtbl->co_alter = obj->o_calter =
4170Sstevel@tonic-gate (Addr)(_strtbl - strtbl);
4180Sstevel@tonic-gate (void) strcpy(_strtbl, _str);
4190Sstevel@tonic-gate _strtbl += strlen(_str) + 1;
4200Sstevel@tonic-gate } else
4210Sstevel@tonic-gate objtbl->co_alter = obj->o_calter;
4220Sstevel@tonic-gate
4230Sstevel@tonic-gate /*
4240Sstevel@tonic-gate * If object identifies the specific application
4250Sstevel@tonic-gate * for which this cache is relevant, record it
4260Sstevel@tonic-gate * in the header.
4270Sstevel@tonic-gate */
4280Sstevel@tonic-gate if ((objtbl->co_flags &
4290Sstevel@tonic-gate (RTC_OBJ_APP | RTC_OBJ_REALPTH)) ==
4300Sstevel@tonic-gate (RTC_OBJ_APP | RTC_OBJ_REALPTH))
4310Sstevel@tonic-gate head->ch_app = _filetbl[_id].cf_obj;
4320Sstevel@tonic-gate
4330Sstevel@tonic-gate /*
4340Sstevel@tonic-gate * Add this object to the hash table.
4350Sstevel@tonic-gate */
4360Sstevel@tonic-gate hashval = ent->e_hash % hashbkts;
4370Sstevel@tonic-gate hashchn[ndx] = hashbkt[hashval];
4380Sstevel@tonic-gate hashbkt[hashval] = ndx++;
4390Sstevel@tonic-gate
4400Sstevel@tonic-gate /*
4410Sstevel@tonic-gate * Increment Rt_obj pointer (make sure pointer
4420Sstevel@tonic-gate * falls on an 8-byte boundary).
4430Sstevel@tonic-gate */
4441976Sab196087 objtbl = (Rtc_obj *)
4451976Sab196087 S_ROUND((uintptr_t)(objtbl + 1),
4460Sstevel@tonic-gate sizeof (Lword));
4470Sstevel@tonic-gate }
4480Sstevel@tonic-gate }
4490Sstevel@tonic-gate
4500Sstevel@tonic-gate /*
4510Sstevel@tonic-gate * Finally pick off any simple filenames.
4520Sstevel@tonic-gate */
4530Sstevel@tonic-gate for (bkt = 0; bkt < stbl->t_size; bkt++) {
4540Sstevel@tonic-gate for (ent = stbl->t_entry[bkt]; ent; ent = ent->e_next) {
4550Sstevel@tonic-gate Word hashval;
4560Sstevel@tonic-gate Hash_obj * obj = ent->e_obj;
4570Sstevel@tonic-gate Rtc_dir * _dirtbl;
4580Sstevel@tonic-gate Rtc_file * _filetbl;
4590Sstevel@tonic-gate int _id;
4600Sstevel@tonic-gate
4610Sstevel@tonic-gate /*
4620Sstevel@tonic-gate * Skip everything except simple filenames.
4630Sstevel@tonic-gate */
4640Sstevel@tonic-gate if (ent->e_off == 0)
4650Sstevel@tonic-gate continue;
4660Sstevel@tonic-gate
4670Sstevel@tonic-gate /*
4680Sstevel@tonic-gate * Assign basic object attributes.
4690Sstevel@tonic-gate */
4700Sstevel@tonic-gate objtbl->co_hash = ent->e_hash;
4710Sstevel@tonic-gate objtbl->co_id = ent->e_id;
4720Sstevel@tonic-gate objtbl->co_flags = obj->o_flags | ent->e_flags;
4730Sstevel@tonic-gate objtbl->co_info = obj->o_info;
4740Sstevel@tonic-gate objtbl->co_alter = obj->o_calter;
4750Sstevel@tonic-gate
4760Sstevel@tonic-gate ent->e_cobj = objtbl;
4770Sstevel@tonic-gate
4780Sstevel@tonic-gate /*
4790Sstevel@tonic-gate * Assign the file name from its full name.
4800Sstevel@tonic-gate */
4811976Sab196087 objtbl->co_name = (Addr)(CAST_PTRINT(char *,
4821976Sab196087 ent->e_path->e_cobj->co_name) + ent->e_off);
4830Sstevel@tonic-gate
4840Sstevel@tonic-gate /*
4850Sstevel@tonic-gate * Add this file to its associated directory.
4860Sstevel@tonic-gate */
4870Sstevel@tonic-gate _dirtbl = &dirtbl[ent->e_id - 1];
4880Sstevel@tonic-gate /* LINTED */
4890Sstevel@tonic-gate _filetbl = (Rtc_file *)
4901976Sab196087 (CAST_PTRINT(char *, _dirtbl->cd_file) +
4911976Sab196087 addr);
4920Sstevel@tonic-gate
4930Sstevel@tonic-gate _id = --ent->e_dir->e_cnt;
4940Sstevel@tonic-gate _filetbl[_id].cf_obj =
4951976Sab196087 CAST_PTRINT(Word, ((char *)objtbl - addr));
4960Sstevel@tonic-gate
4970Sstevel@tonic-gate /*
4980Sstevel@tonic-gate * Add this object to the hash table.
4990Sstevel@tonic-gate */
5000Sstevel@tonic-gate hashval = ent->e_hash % hashbkts;
5010Sstevel@tonic-gate hashchn[ndx] = hashbkt[hashval];
5020Sstevel@tonic-gate hashbkt[hashval] = ndx++;
5030Sstevel@tonic-gate
5040Sstevel@tonic-gate /*
5050Sstevel@tonic-gate * Increment Rt_obj pointer (make sure pointer
5060Sstevel@tonic-gate * falls on an 8-byte boundary).
5070Sstevel@tonic-gate */
5081976Sab196087 objtbl = (Rtc_obj *)
5091976Sab196087 S_ROUND((uintptr_t)(objtbl + 1),
5100Sstevel@tonic-gate sizeof (Lword));
5110Sstevel@tonic-gate }
5120Sstevel@tonic-gate }
5130Sstevel@tonic-gate }
5140Sstevel@tonic-gate
5150Sstevel@tonic-gate /*
5160Sstevel@tonic-gate * Add any library, or secure path definitions.
5170Sstevel@tonic-gate */
5180Sstevel@tonic-gate if (crle->c_edlibpath) {
5190Sstevel@tonic-gate head->ch_edlibpath = head->ch_str + (_strtbl - strtbl);
5200Sstevel@tonic-gate
5210Sstevel@tonic-gate (void) strcpy(_strtbl, crle->c_edlibpath);
5220Sstevel@tonic-gate _strtbl += strlen((char *)crle->c_edlibpath) + 1;
5230Sstevel@tonic-gate } else
5240Sstevel@tonic-gate head->ch_edlibpath = 0;
5250Sstevel@tonic-gate
5260Sstevel@tonic-gate if (crle->c_adlibpath) {
5270Sstevel@tonic-gate head->ch_adlibpath = head->ch_str + (_strtbl - strtbl);
5280Sstevel@tonic-gate
5290Sstevel@tonic-gate (void) strcpy(_strtbl, crle->c_adlibpath);
5300Sstevel@tonic-gate _strtbl += strlen((char *)crle->c_adlibpath) + 1;
5310Sstevel@tonic-gate } else
5320Sstevel@tonic-gate head->ch_adlibpath = 0;
5330Sstevel@tonic-gate
5340Sstevel@tonic-gate if (crle->c_eslibpath) {
5350Sstevel@tonic-gate head->ch_eslibpath = head->ch_str + (_strtbl - strtbl);
5360Sstevel@tonic-gate
5370Sstevel@tonic-gate (void) strcpy(_strtbl, crle->c_eslibpath);
5380Sstevel@tonic-gate _strtbl += strlen((char *)crle->c_eslibpath) + 1;
5390Sstevel@tonic-gate } else
5400Sstevel@tonic-gate head->ch_eslibpath = 0;
5410Sstevel@tonic-gate
5420Sstevel@tonic-gate if (crle->c_aslibpath) {
5430Sstevel@tonic-gate head->ch_aslibpath = head->ch_str + (_strtbl - strtbl);
5440Sstevel@tonic-gate
5450Sstevel@tonic-gate (void) strcpy(_strtbl, crle->c_aslibpath);
5460Sstevel@tonic-gate _strtbl += strlen((char *)crle->c_aslibpath) + 1;
5470Sstevel@tonic-gate } else
5480Sstevel@tonic-gate head->ch_aslibpath = 0;
5490Sstevel@tonic-gate
5500Sstevel@tonic-gate /*
5510Sstevel@tonic-gate * Add any environment variable entries.
5520Sstevel@tonic-gate */
5530Sstevel@tonic-gate if (crle->c_envnum) {
554*9131SRod.Evans@Sun.COM Env_desc *env;
555*9131SRod.Evans@Sun.COM Aliste idx;
5560Sstevel@tonic-gate
557*9131SRod.Evans@Sun.COM for (APLIST_TRAVERSE(crle->c_env, idx, env)) {
5580Sstevel@tonic-gate envtbl->env_str = head->ch_str + (_strtbl - strtbl);
5590Sstevel@tonic-gate envtbl->env_flags = env->e_flags;
5600Sstevel@tonic-gate
5610Sstevel@tonic-gate (void) strcpy(_strtbl, env->e_str);
5620Sstevel@tonic-gate _strtbl += env->e_totsz;
5630Sstevel@tonic-gate
5640Sstevel@tonic-gate envtbl++;
5650Sstevel@tonic-gate }
5660Sstevel@tonic-gate envtbl->env_str = 0;
5670Sstevel@tonic-gate envtbl->env_flags = 0;
5680Sstevel@tonic-gate }
5690Sstevel@tonic-gate
5700Sstevel@tonic-gate /*
5710Sstevel@tonic-gate * Add any filter/filtee association entries.
5720Sstevel@tonic-gate */
5730Sstevel@tonic-gate if (crle->c_fltrnum) {
574*9131SRod.Evans@Sun.COM Flt_desc *flt;
575*9131SRod.Evans@Sun.COM Aliste idx1;
5760Sstevel@tonic-gate
577*9131SRod.Evans@Sun.COM for (APLIST_TRAVERSE(crle->c_flt, idx1, flt)) {
578*9131SRod.Evans@Sun.COM Hash_ent *flte;
579*9131SRod.Evans@Sun.COM Aliste idx2;
5800Sstevel@tonic-gate
5810Sstevel@tonic-gate /*
5820Sstevel@tonic-gate * Establish the filter name, and filtee string, as
5830Sstevel@tonic-gate * offsets into the configuration files string table.
5840Sstevel@tonic-gate * Establish the filtee as the offset into the filtee
5850Sstevel@tonic-gate * table.
5860Sstevel@tonic-gate */
5870Sstevel@tonic-gate fltrtbl->fr_filter = flt->f_fent->e_cobj->co_name;
5880Sstevel@tonic-gate fltrtbl->fr_string = _strtbl - strtbl;
5890Sstevel@tonic-gate (void) strcpy(_strtbl, flt->f_str);
5900Sstevel@tonic-gate _strtbl += flt->f_strsz;
5911976Sab196087 fltrtbl->fr_filtee = (Word)
5921976Sab196087 ((uintptr_t)_fltetbl - (uintptr_t)fltetbl);
5930Sstevel@tonic-gate
594*9131SRod.Evans@Sun.COM for (APLIST_TRAVERSE(flt->f_filtee, idx2, flte)) {
5950Sstevel@tonic-gate /*
5960Sstevel@tonic-gate * Establish the filtee name as the offset into
5970Sstevel@tonic-gate * the configuration files string table.
5980Sstevel@tonic-gate */
5990Sstevel@tonic-gate _fltetbl->fe_filtee = flte->e_cobj->co_name;
6000Sstevel@tonic-gate _fltetbl++;
6010Sstevel@tonic-gate }
6020Sstevel@tonic-gate _fltetbl->fe_filtee = 0;
6030Sstevel@tonic-gate _fltetbl++, fltrtbl++;
6040Sstevel@tonic-gate }
6050Sstevel@tonic-gate fltrtbl->fr_filter = 0;
6060Sstevel@tonic-gate fltrtbl->fr_filtee = 0;
6070Sstevel@tonic-gate }
6080Sstevel@tonic-gate
6090Sstevel@tonic-gate /*
6100Sstevel@tonic-gate * Flush everything out.
6110Sstevel@tonic-gate */
6120Sstevel@tonic-gate (void) close(crle->c_tempfd);
6131976Sab196087 if (msync((void *)crle->c_tempaddr, crle->c_tempsize, MS_ASYNC) == -1) {
6140Sstevel@tonic-gate int err = errno;
6150Sstevel@tonic-gate (void) fprintf(stderr, MSG_INTL(MSG_SYS_TRUNC),
6160Sstevel@tonic-gate crle->c_name, crle->c_tempname, strerror(err));
6170Sstevel@tonic-gate return (1);
6180Sstevel@tonic-gate }
6190Sstevel@tonic-gate
6200Sstevel@tonic-gate return (0);
6210Sstevel@tonic-gate }
6220Sstevel@tonic-gate
6230Sstevel@tonic-gate /*
6240Sstevel@tonic-gate * Update a configuration file. If dldump()'ed images have been created then
6250Sstevel@tonic-gate * the memory reservation of those images is added to the configuration file.
6260Sstevel@tonic-gate * The temporary file is then moved into its final resting place.
6270Sstevel@tonic-gate */
628238Sseizo int
updateconfig(Crle_desc * crle)6290Sstevel@tonic-gate updateconfig(Crle_desc * crle)
6300Sstevel@tonic-gate {
6311976Sab196087 Rtc_head *head = (Rtc_head *)crle->c_tempheadaddr;
6320Sstevel@tonic-gate
6330Sstevel@tonic-gate if (crle->c_flags & CRLE_DUMP) {
6340Sstevel@tonic-gate head->ch_cnflags &= ~RTC_HDR_IGNORE;
6350Sstevel@tonic-gate
6360Sstevel@tonic-gate if (msync((void *)crle->c_tempaddr, crle->c_tempsize,
6370Sstevel@tonic-gate MS_ASYNC) == -1) {
6380Sstevel@tonic-gate int err = errno;
6390Sstevel@tonic-gate (void) fprintf(stderr, MSG_INTL(MSG_SYS_TRUNC),
6400Sstevel@tonic-gate crle->c_name, crle->c_tempname, strerror(err));
6410Sstevel@tonic-gate return (1);
6420Sstevel@tonic-gate }
6430Sstevel@tonic-gate }
6440Sstevel@tonic-gate
6450Sstevel@tonic-gate /*
6460Sstevel@tonic-gate * If an original configuration file exists, remove it.
6470Sstevel@tonic-gate */
6480Sstevel@tonic-gate if (crle->c_flags & CRLE_EXISTS)
6490Sstevel@tonic-gate (void) unlink(crle->c_confil);
6500Sstevel@tonic-gate
6510Sstevel@tonic-gate /*
6520Sstevel@tonic-gate * Move the config file to its final resting place. If the two files
6530Sstevel@tonic-gate * exist on the same filesystem a rename is sufficient.
6540Sstevel@tonic-gate */
6550Sstevel@tonic-gate if (crle->c_flags & CRLE_DIFFDEV) {
6560Sstevel@tonic-gate int fd;
6570Sstevel@tonic-gate
6580Sstevel@tonic-gate if ((fd = open(crle->c_confil, (O_RDWR | O_CREAT | O_TRUNC),
6590Sstevel@tonic-gate 0666)) == -1) {
6600Sstevel@tonic-gate int err = errno;
6610Sstevel@tonic-gate (void) fprintf(stderr, MSG_INTL(MSG_SYS_OPEN),
6620Sstevel@tonic-gate crle->c_name, crle->c_confil, strerror(err));
6630Sstevel@tonic-gate return (1);
6640Sstevel@tonic-gate }
6650Sstevel@tonic-gate if (write(fd, (void *)crle->c_tempaddr, crle->c_tempsize) !=
6660Sstevel@tonic-gate crle->c_tempsize) {
6670Sstevel@tonic-gate int err = errno;
6680Sstevel@tonic-gate (void) fprintf(stderr, MSG_INTL(MSG_SYS_WRITE),
6690Sstevel@tonic-gate crle->c_name, crle->c_confil, strerror(err));
6700Sstevel@tonic-gate return (1);
6710Sstevel@tonic-gate }
6720Sstevel@tonic-gate (void) close(fd);
6730Sstevel@tonic-gate (void) unlink(crle->c_tempname);
6740Sstevel@tonic-gate } else
6750Sstevel@tonic-gate (void) rename(crle->c_tempname, crle->c_confil);
6760Sstevel@tonic-gate
6770Sstevel@tonic-gate return (0);
6780Sstevel@tonic-gate }
679