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