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 51618Srie * Common Development and Distribution License (the "License"). 61618Srie * 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 */ 211618Srie 220Sstevel@tonic-gate /* 23*4734Sab196087 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 240Sstevel@tonic-gate * Use is subject to license terms. 250Sstevel@tonic-gate */ 260Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 270Sstevel@tonic-gate 280Sstevel@tonic-gate #include <sys/types.h> 290Sstevel@tonic-gate #include <sys/stat.h> 300Sstevel@tonic-gate #include <sys/mman.h> 310Sstevel@tonic-gate #include <fcntl.h> 320Sstevel@tonic-gate #include <stdio.h> 330Sstevel@tonic-gate #include <string.h> 340Sstevel@tonic-gate #include <unistd.h> 350Sstevel@tonic-gate #include <errno.h> 360Sstevel@tonic-gate #include <limits.h> 370Sstevel@tonic-gate #include <alloca.h> 380Sstevel@tonic-gate #include "sgs.h" 390Sstevel@tonic-gate #include "rtc.h" 400Sstevel@tonic-gate #include "conv.h" 410Sstevel@tonic-gate #include "_crle.h" 420Sstevel@tonic-gate #include "msg.h" 430Sstevel@tonic-gate 440Sstevel@tonic-gate 450Sstevel@tonic-gate /* 460Sstevel@tonic-gate * Display the command line required to regenerate the configuration file. 470Sstevel@tonic-gate * 480Sstevel@tonic-gate * Under normal mode the command is printed on one line to make it more 490Sstevel@tonic-gate * available for grep(1) use. Under verbose mode the command is separated 500Sstevel@tonic-gate * into each argument (a little more readable perhaps when the arguments are 510Sstevel@tonic-gate * numerous of have long pathnames). 520Sstevel@tonic-gate * 530Sstevel@tonic-gate * Note that for version 1 configuration files we never used to generate any 540Sstevel@tonic-gate * command-line information, and as the attempt to do so is only a best effort 550Sstevel@tonic-gate * don't bother printing anything. 560Sstevel@tonic-gate */ 570Sstevel@tonic-gate static void 580Sstevel@tonic-gate printcmd(Crle_desc * crle, Rtc_head * head, List * cmdline) 590Sstevel@tonic-gate { 600Sstevel@tonic-gate Listnode *lnp; 610Sstevel@tonic-gate const char *fmto, *fmtb, *fmtm, *fmte; 620Sstevel@tonic-gate char *cmd; 630Sstevel@tonic-gate int output = 0; 640Sstevel@tonic-gate 650Sstevel@tonic-gate if (crle->c_flags & CRLE_VERBOSE) { 660Sstevel@tonic-gate fmto = MSG_INTL(MSG_DMP_CMD_ONE_V); 670Sstevel@tonic-gate fmtb = MSG_INTL(MSG_DMP_CMD_BGN_V); 680Sstevel@tonic-gate fmtm = MSG_INTL(MSG_DMP_CMD_MID_V); 690Sstevel@tonic-gate fmte = MSG_INTL(MSG_DMP_CMD_END_V); 700Sstevel@tonic-gate 710Sstevel@tonic-gate } else if (head->ch_version > RTC_VER_ONE) { 720Sstevel@tonic-gate fmto = MSG_INTL(MSG_DMP_CMD_ONE); 730Sstevel@tonic-gate fmtb = MSG_INTL(MSG_DMP_CMD_BGN); 740Sstevel@tonic-gate fmtm = MSG_INTL(MSG_DMP_CMD_MID); 750Sstevel@tonic-gate fmte = MSG_INTL(MSG_DMP_CMD_END); 760Sstevel@tonic-gate 770Sstevel@tonic-gate } else { 780Sstevel@tonic-gate (void) printf(MSG_ORIG(MSG_STR_NL)); 790Sstevel@tonic-gate return; 800Sstevel@tonic-gate } 810Sstevel@tonic-gate 820Sstevel@tonic-gate (void) printf(MSG_INTL(MSG_DMP_CMD_TITLE)); 830Sstevel@tonic-gate for (LIST_TRAVERSE(cmdline, lnp, cmd)) { 840Sstevel@tonic-gate if (output++ == 0) { 850Sstevel@tonic-gate if (lnp->next) 860Sstevel@tonic-gate (void) printf(fmtb, cmd); 870Sstevel@tonic-gate else 880Sstevel@tonic-gate (void) printf(fmto, cmd); 890Sstevel@tonic-gate } else { 900Sstevel@tonic-gate if (lnp->next) 910Sstevel@tonic-gate (void) printf(fmtm, cmd); 920Sstevel@tonic-gate else 930Sstevel@tonic-gate (void) printf(fmte, cmd); 940Sstevel@tonic-gate } 950Sstevel@tonic-gate } 960Sstevel@tonic-gate } 970Sstevel@tonic-gate 980Sstevel@tonic-gate /* 990Sstevel@tonic-gate * Establish the argument required to generate the associated object. 1000Sstevel@tonic-gate */ 1010Sstevel@tonic-gate static const char * 1020Sstevel@tonic-gate getformat(Half flags) 1030Sstevel@tonic-gate { 1040Sstevel@tonic-gate if (flags & RTC_OBJ_ALTER) { 1050Sstevel@tonic-gate if (flags & RTC_OBJ_DUMP) { 1060Sstevel@tonic-gate if (flags & RTC_OBJ_GROUP) 1070Sstevel@tonic-gate return (MSG_ORIG(MSG_CMD_DUMPGRP)); 1080Sstevel@tonic-gate else 1090Sstevel@tonic-gate return (MSG_ORIG(MSG_CMD_DUMPIND)); 1100Sstevel@tonic-gate } else { 1110Sstevel@tonic-gate if (flags & RTC_OBJ_OPTINAL) 1120Sstevel@tonic-gate return (MSG_ORIG(MSG_CMD_OPTIONAL)); 1130Sstevel@tonic-gate else 1140Sstevel@tonic-gate return (MSG_ORIG(MSG_CMD_ALTER)); 1150Sstevel@tonic-gate } 1160Sstevel@tonic-gate } else { 1170Sstevel@tonic-gate if (flags & RTC_OBJ_GROUP) 1180Sstevel@tonic-gate return (MSG_ORIG(MSG_CMD_GRP)); 1190Sstevel@tonic-gate else 1200Sstevel@tonic-gate return (MSG_ORIG(MSG_CMD_IND)); 1210Sstevel@tonic-gate } 1220Sstevel@tonic-gate } 1230Sstevel@tonic-gate 1240Sstevel@tonic-gate /* 1250Sstevel@tonic-gate * Fabricate a system default search path. If an update is requested, and 1260Sstevel@tonic-gate * new search paths are specified while no configuration file exists, or if a 1270Sstevel@tonic-gate * configuration file does exist but doesn't specify this particular search 1280Sstevel@tonic-gate * path, create any system defaults. The intent is to allow 1290Sstevel@tonic-gate * "crle -u -l/usr/local/lib" and have this append the search path to the 1300Sstevel@tonic-gate * system default, rather than have the user have to determine and specify 1310Sstevel@tonic-gate * this default themselves. 1320Sstevel@tonic-gate */ 1330Sstevel@tonic-gate static int 1340Sstevel@tonic-gate fablib(Crle_desc * crle, int flag) 1350Sstevel@tonic-gate { 1360Sstevel@tonic-gate const char *path; 1370Sstevel@tonic-gate char **list; 1380Sstevel@tonic-gate 1390Sstevel@tonic-gate switch (flag) { 1400Sstevel@tonic-gate case CRLE_EDLIB: 1411976Sab196087 #if M_CLASS == ELFCLASS64 1420Sstevel@tonic-gate #ifndef SGS_PRE_UNIFIED_PROCESS 1431976Sab196087 path = MSG_ORIG(MSG_PTH_NEWDLP_64); 1440Sstevel@tonic-gate #else 1451976Sab196087 path = MSG_ORIG(MSG_PTH_OLDDLP_64); 1460Sstevel@tonic-gate #endif 1471976Sab196087 #else 1480Sstevel@tonic-gate #ifndef SGS_PRE_UNIFIED_PROCESS 1491976Sab196087 path = MSG_ORIG(MSG_PTH_NEWDLP); 1500Sstevel@tonic-gate #else 1511976Sab196087 path = MSG_ORIG(MSG_PTH_OLDDLP); 1520Sstevel@tonic-gate #endif 1531976Sab196087 #endif 1540Sstevel@tonic-gate list = &crle->c_edlibpath; 1550Sstevel@tonic-gate break; 1560Sstevel@tonic-gate 1570Sstevel@tonic-gate case CRLE_ESLIB: 1581976Sab196087 #if M_CLASS == ELFCLASS64 1590Sstevel@tonic-gate #ifndef SGS_PRE_UNIFIED_PROCESS 1601976Sab196087 path = MSG_ORIG(MSG_PTH_NEWTD_64); 1610Sstevel@tonic-gate #else 1621976Sab196087 path = MSG_ORIG(MSG_PTH_OLDTD_64); 1630Sstevel@tonic-gate #endif 1641976Sab196087 #else 1650Sstevel@tonic-gate #ifndef SGS_PRE_UNIFIED_PROCESS 1661976Sab196087 path = MSG_ORIG(MSG_PTH_NEWTD); 1670Sstevel@tonic-gate #else 1681976Sab196087 path = MSG_ORIG(MSG_PTH_OLDTD); 1690Sstevel@tonic-gate #endif 1701976Sab196087 #endif 1710Sstevel@tonic-gate list = &crle->c_eslibpath; 1720Sstevel@tonic-gate break; 1730Sstevel@tonic-gate 1740Sstevel@tonic-gate case CRLE_ADLIB: 1750Sstevel@tonic-gate path = MSG_ORIG(MSG_PTH_AOUTDLP); 1760Sstevel@tonic-gate list = &crle->c_adlibpath; 1770Sstevel@tonic-gate break; 1780Sstevel@tonic-gate 1790Sstevel@tonic-gate case CRLE_ASLIB: 1800Sstevel@tonic-gate path = MSG_ORIG(MSG_PTH_AOUTTD); 1810Sstevel@tonic-gate list = &crle->c_aslibpath; 1820Sstevel@tonic-gate break; 1830Sstevel@tonic-gate 1840Sstevel@tonic-gate default: 1850Sstevel@tonic-gate return (1); 1860Sstevel@tonic-gate } 1870Sstevel@tonic-gate 1880Sstevel@tonic-gate return (addlib(crle, list, path)); 1890Sstevel@tonic-gate } 1900Sstevel@tonic-gate 1910Sstevel@tonic-gate /* 1920Sstevel@tonic-gate * Establish the flags required to generate the associated object. Actually 1930Sstevel@tonic-gate * the flags are already part of the object being inspected from the present 1940Sstevel@tonic-gate * configuration file, but instead of using them all, which can cause some 1950Sstevel@tonic-gate * unsuspected propagation down the inspect() family, only use those flags that 1960Sstevel@tonic-gate * would have been contributed from crle()'s calls to inspect. 1970Sstevel@tonic-gate */ 1980Sstevel@tonic-gate static Half 1990Sstevel@tonic-gate getflags(Half flags) 2000Sstevel@tonic-gate { 2010Sstevel@tonic-gate flags &= 2020Sstevel@tonic-gate (RTC_OBJ_ALTER | RTC_OBJ_DUMP | RTC_OBJ_GROUP | RTC_OBJ_OPTINAL); 2030Sstevel@tonic-gate return (flags | RTC_OBJ_CMDLINE); 2040Sstevel@tonic-gate } 2050Sstevel@tonic-gate 2060Sstevel@tonic-gate /* 2070Sstevel@tonic-gate * Dump a configuration files information. This routine is very close to the 2080Sstevel@tonic-gate * scanconfig() in libcrle. 2090Sstevel@tonic-gate */ 2102056Sab196087 /*ARGSUSED2*/ 2111976Sab196087 static INSCFG_RET 2122056Sab196087 scanconfig(Crle_desc * crle, Addr addr, int c_class) 2130Sstevel@tonic-gate { 214*4734Sab196087 Conv_inv_buf_t inv_buf1, inv_buf2, inv_buf3, inv_buf4; 215*4734Sab196087 Conv_dl_flag_buf_t dl_flag_buf; 2161976Sab196087 Rtc_id *id; 2171976Sab196087 Rtc_head *head; 2180Sstevel@tonic-gate Rtc_dir *dirtbl; 2190Sstevel@tonic-gate Rtc_file *filetbl; 2200Sstevel@tonic-gate Rtc_obj *objtbl, * obj; 2210Sstevel@tonic-gate Word *hash, * chain; 2220Sstevel@tonic-gate const char *strtbl; 2230Sstevel@tonic-gate int ndx, bkts; 2240Sstevel@tonic-gate List cmdline = { 0 }; 2250Sstevel@tonic-gate char _cmd[PATH_MAX], * cmd; 2260Sstevel@tonic-gate char _objdir[PATH_MAX], * objdir = 0; 2270Sstevel@tonic-gate 2281976Sab196087 2291976Sab196087 /* 2301976Sab196087 * If there is an Rtc_id present, the Rtc_head follows it. 2311976Sab196087 * Otherwise, it is at the top. 2321976Sab196087 */ 2331976Sab196087 if (RTC_ID_TEST(addr)) { 2341976Sab196087 id = (Rtc_id *) addr; 2351976Sab196087 addr += sizeof (*id); /* Rtc_head follows */ 2361976Sab196087 } else { 2371976Sab196087 id = NULL; 2381976Sab196087 /* 2391976Sab196087 * When updating an existing config file that is lacking 2401976Sab196087 * the Rtc_id block, don't put one into the resulting file. 2411976Sab196087 */ 2421976Sab196087 crle->c_flags &= ~CRLE_ADDID; 2431976Sab196087 } 2441976Sab196087 head = (Rtc_head *) addr; 2451976Sab196087 2461976Sab196087 2471976Sab196087 /* 2481976Sab196087 * The rest of the configuration file can only be examined by 2491976Sab196087 * a program of the same ELFCLASS, byte order, and hardware 2501976Sab196087 * architecture as the one that created it. 2511976Sab196087 */ 2521976Sab196087 #ifdef _ELF64 2531976Sab196087 /* 64-bit program with an existing 32-bit file? Abort. */ 2541976Sab196087 if (!(head->ch_cnflags & RTC_HDR_64)) { 2551976Sab196087 (void) fprintf(stderr, MSG_INTL(MSG_ARG_CLASS), 256*4734Sab196087 crle->c_name, crle->c_confil); 2571976Sab196087 return (INSCFG_RET_FAIL); 2581976Sab196087 } 2591976Sab196087 #else 2601976Sab196087 /* 32-bit program with an existing 64-bit file? Restart. */ 2611976Sab196087 if (head->ch_cnflags & RTC_HDR_64) 2621976Sab196087 return (INSCFG_RET_NEED64); 2632056Sab196087 2642056Sab196087 /* 2652056Sab196087 * 32-bit program with an existing 32-bit file, but the 2662056Sab196087 * user specified the -64 option? Abort 2672056Sab196087 */ 2682056Sab196087 if (c_class != ELFCLASS32) { 2692056Sab196087 (void) fprintf(stderr, MSG_INTL(MSG_ARG_CLASS), 270*4734Sab196087 crle->c_name, crle->c_confil); 2712056Sab196087 return (INSCFG_RET_FAIL); 2722056Sab196087 } 2731976Sab196087 #endif 2741976Sab196087 /* 2751976Sab196087 * Now that the ELFCLASS has been settled, ensure that the 2761976Sab196087 * byte order and hardware match. Unlike ELFCLASS, where restarting 2771976Sab196087 * the other version is an option, we cannot work around a mismatch 2781976Sab196087 * of these attributes. 2791976Sab196087 */ 2801976Sab196087 if (id) { /* Rtc_id is present */ 2811976Sab196087 /* 2821976Sab196087 * Was the file produced by compatible hardware? 2831976Sab196087 * ELFCLASS doesn't matter here, because we can 2841976Sab196087 * adjust for that, but byte order and machine type do. 2851976Sab196087 */ 2861976Sab196087 if ((id->id_data != M_DATA) || (id->id_machine != M_MACH)) { 2871976Sab196087 (void) fprintf(stderr, MSG_INTL(MSG_ARG_WRONGARCH), 2881976Sab196087 crle->c_name, crle->c_confil, 289*4734Sab196087 conv_ehdr_data(id->id_data, CONV_FMT_ALTFILE, 290*4734Sab196087 &inv_buf1), 291*4734Sab196087 conv_ehdr_mach(id->id_machine, CONV_FMT_ALTFILE, 292*4734Sab196087 &inv_buf2), 293*4734Sab196087 conv_ehdr_data(M_DATA, CONV_FMT_ALTFILE, &inv_buf3), 294*4734Sab196087 conv_ehdr_mach(M_MACH, CONV_FMT_ALTFILE, 295*4734Sab196087 &inv_buf4)); 2961976Sab196087 return (INSCFG_RET_FAIL); 2971976Sab196087 } 2981976Sab196087 } 2991976Sab196087 3001976Sab196087 3010Sstevel@tonic-gate /* LINTED */ 3021976Sab196087 objtbl = (Rtc_obj *)(CAST_PTRINT(char *, head->ch_obj) + addr); 3031976Sab196087 strtbl = (const char *)(CAST_PTRINT(char *, head->ch_str) + addr); 3041976Sab196087 3051976Sab196087 /* 3061976Sab196087 * If the configuration file has a version higher than we 3071976Sab196087 * recognise, we face two issues: 3081976Sab196087 * (1) Updates are not possible because we have no 3091976Sab196087 * way to recognise or propagate the new features. 3101976Sab196087 * This has to be a fatal error. 3111976Sab196087 * (2) Printing has the risk that we may have been 3121976Sab196087 * handed something other than a real config file, as 3131976Sab196087 * well as the fact that we can't display the information 3141976Sab196087 * for the new features. So, we print a warning, but 3151976Sab196087 * continue on to do the best we can with it. 3161976Sab196087 */ 3171976Sab196087 if (head->ch_version > RTC_VER_CURRENT) { 3181976Sab196087 if (crle->c_flags & CRLE_UPDATE) { 3191976Sab196087 (void) fprintf(stderr, MSG_INTL(MSG_ARG_UPDATEVER), 320*4734Sab196087 crle->c_name, crle->c_confil, 321*4734Sab196087 (int)head->ch_version, RTC_VER_CURRENT); 3221976Sab196087 return (INSCFG_RET_FAIL); 3231976Sab196087 } else { 3241976Sab196087 (void) fprintf(stderr, MSG_INTL(MSG_ARG_PRINTVER), 325*4734Sab196087 crle->c_name, crle->c_confil, 326*4734Sab196087 (int)head->ch_version, RTC_VER_CURRENT); 3271976Sab196087 } 3281976Sab196087 } 3290Sstevel@tonic-gate 3300Sstevel@tonic-gate /* 3310Sstevel@tonic-gate * If this is a version 1 configuration file we can't generate accurate 3320Sstevel@tonic-gate * update information, or the command-line used to create the file. 3330Sstevel@tonic-gate */ 3340Sstevel@tonic-gate if (head->ch_version == RTC_VER_ONE) { 3350Sstevel@tonic-gate (void) printf(MSG_INTL(MSG_ARG_UPDATE), crle->c_name, 3362056Sab196087 crle->c_confil, (int)head->ch_version); 3370Sstevel@tonic-gate } 3380Sstevel@tonic-gate 3391976Sab196087 3401976Sab196087 if (!(crle->c_flags & CRLE_UPDATE) && (head->ch_cnflags & RTC_HDR_64)) { 3411976Sab196087 /* 3421976Sab196087 * Construct the original command line argument. 3431976Sab196087 */ 3441976Sab196087 cmd = strcpy(alloca(MSG_CMD_64_SIZE + 1), MSG_ORIG(MSG_CMD_64)); 3451976Sab196087 if (list_append(&cmdline, cmd) == 0) 3461976Sab196087 return (INSCFG_RET_FAIL); 3470Sstevel@tonic-gate } 3480Sstevel@tonic-gate 3491976Sab196087 3500Sstevel@tonic-gate /* 3510Sstevel@tonic-gate * Start analyzing the configuration files header information. 3520Sstevel@tonic-gate */ 3530Sstevel@tonic-gate if ((crle->c_flags & CRLE_UPDATE) == 0) { 3540Sstevel@tonic-gate const char *fmt; 3550Sstevel@tonic-gate 3560Sstevel@tonic-gate if (head->ch_dlflags) 357*4734Sab196087 fmt = conv_dl_flag(head->ch_dlflags, 0, &dl_flag_buf); 3580Sstevel@tonic-gate else 3590Sstevel@tonic-gate fmt = MSG_ORIG(MSG_STR_EMPTY); 3600Sstevel@tonic-gate 3612056Sab196087 (void) printf(MSG_INTL(MSG_DMP_HEAD), (int)head->ch_version, 3620Sstevel@tonic-gate crle->c_confil, fmt); 3630Sstevel@tonic-gate 3640Sstevel@tonic-gate /* 3651976Sab196087 * If the file has an id block, show the information 3661976Sab196087 */ 3671976Sab196087 if (id) 368*4734Sab196087 (void) printf(MSG_INTL(MSG_DMP_PLATFORM), 369*4734Sab196087 conv_ehdr_class(id->id_class, CONV_FMT_ALTFILE, 370*4734Sab196087 &inv_buf1), 371*4734Sab196087 conv_ehdr_data(id->id_data, CONV_FMT_ALTFILE, 372*4734Sab196087 &inv_buf2), 373*4734Sab196087 conv_ehdr_mach(id->id_machine, CONV_FMT_ALTFILE, 374*4734Sab196087 &inv_buf3)); 3751976Sab196087 3761976Sab196087 /* 3770Sstevel@tonic-gate * Construct the original command line argument. 3780Sstevel@tonic-gate */ 3790Sstevel@tonic-gate (void) snprintf(_cmd, PATH_MAX, MSG_ORIG(MSG_CMD_CONF), 3800Sstevel@tonic-gate crle->c_confil); 3810Sstevel@tonic-gate cmd = strcpy(alloca(strlen(_cmd) + 1), _cmd); 3820Sstevel@tonic-gate if (list_append(&cmdline, cmd) == 0) 3831976Sab196087 return (INSCFG_RET_FAIL); 3840Sstevel@tonic-gate 3850Sstevel@tonic-gate /* 3860Sstevel@tonic-gate * Construct any -f usage. 3870Sstevel@tonic-gate */ 3880Sstevel@tonic-gate if (head->ch_dlflags && 3890Sstevel@tonic-gate (head->ch_dlflags != RTLD_REL_RELATIVE)) { 3900Sstevel@tonic-gate (void) snprintf(_cmd, PATH_MAX, MSG_ORIG(MSG_CMD_FLAGS), 391*4734Sab196087 conv_dl_flag(head->ch_dlflags, CONV_FMT_ALTCRLE, 392*4734Sab196087 &dl_flag_buf)); 3930Sstevel@tonic-gate cmd = strcpy(alloca(strlen(_cmd) + 1), _cmd); 3940Sstevel@tonic-gate if (list_append(&cmdline, cmd) == 0) 3951976Sab196087 return (INSCFG_RET_FAIL); 3960Sstevel@tonic-gate } 3970Sstevel@tonic-gate } else { 3980Sstevel@tonic-gate /* 3990Sstevel@tonic-gate * Establish any -f usage. 4000Sstevel@tonic-gate */ 4010Sstevel@tonic-gate if (head->ch_dlflags && 4020Sstevel@tonic-gate (head->ch_dlflags != RTLD_REL_RELATIVE)) 4030Sstevel@tonic-gate crle->c_dlflags = head->ch_dlflags; 4040Sstevel@tonic-gate } 4050Sstevel@tonic-gate 4060Sstevel@tonic-gate 4070Sstevel@tonic-gate /* 4080Sstevel@tonic-gate * Determine if this configuration file is only applicable to a specific 4090Sstevel@tonic-gate * application. 4100Sstevel@tonic-gate */ 4110Sstevel@tonic-gate if (head->ch_app) { 4120Sstevel@tonic-gate char *alter; 4130Sstevel@tonic-gate 4140Sstevel@tonic-gate obj = (Rtc_obj *)(head->ch_app + addr); 4150Sstevel@tonic-gate 4160Sstevel@tonic-gate /* 4170Sstevel@tonic-gate * Determine the output directory for the files 4180Sstevel@tonic-gate * alternative name. 4190Sstevel@tonic-gate */ 4200Sstevel@tonic-gate alter = (char *)(strtbl + obj->co_alter); 4210Sstevel@tonic-gate (void) strcpy(_objdir, alter); 4220Sstevel@tonic-gate alter = strrchr(_objdir, '/'); 4230Sstevel@tonic-gate *alter = '\0'; 4240Sstevel@tonic-gate 4250Sstevel@tonic-gate crle->c_objdir = objdir = _objdir; 4260Sstevel@tonic-gate 4270Sstevel@tonic-gate if (crle->c_flags & CRLE_UPDATE) { 4280Sstevel@tonic-gate if (inspect(crle, (strtbl + obj->co_name), 4290Sstevel@tonic-gate (RTC_OBJ_DUMP | RTC_OBJ_ALTER | 4300Sstevel@tonic-gate RTC_OBJ_GROUP | RTC_OBJ_CMDLINE)) != 0) 4311976Sab196087 return (INSCFG_RET_FAIL); 4320Sstevel@tonic-gate } else { 4330Sstevel@tonic-gate (void) printf(MSG_INTL(MSG_DMP_APP), 4340Sstevel@tonic-gate (strtbl + obj->co_alter), (strtbl + obj->co_name)); 4350Sstevel@tonic-gate 4360Sstevel@tonic-gate /* 4370Sstevel@tonic-gate * Construct the original command line arguments. 4380Sstevel@tonic-gate */ 4390Sstevel@tonic-gate (void) snprintf(_cmd, PATH_MAX, 4400Sstevel@tonic-gate MSG_ORIG(MSG_CMD_OUTPUT), crle->c_objdir); 4410Sstevel@tonic-gate cmd = strcpy(alloca(strlen(_cmd) + 1), _cmd); 4420Sstevel@tonic-gate if (list_append(&cmdline, cmd) == 0) 4431976Sab196087 return (INSCFG_RET_FAIL); 4440Sstevel@tonic-gate 4450Sstevel@tonic-gate (void) snprintf(_cmd, PATH_MAX, 4460Sstevel@tonic-gate MSG_ORIG(MSG_CMD_DUMPGRP), (strtbl + obj->co_name)); 4470Sstevel@tonic-gate cmd = strcpy(alloca(strlen(_cmd) + 1), _cmd); 4480Sstevel@tonic-gate if (list_append(&cmdline, cmd) == 0) 4491976Sab196087 return (INSCFG_RET_FAIL); 4500Sstevel@tonic-gate } 4510Sstevel@tonic-gate } 4520Sstevel@tonic-gate 4530Sstevel@tonic-gate /* 4540Sstevel@tonic-gate * Analyze any alternative library path and trusted directory entries. 4550Sstevel@tonic-gate */ 4560Sstevel@tonic-gate if (head->ch_edlibpath) { 4570Sstevel@tonic-gate const char *str; 4580Sstevel@tonic-gate 4590Sstevel@tonic-gate str = (const char *)(head->ch_edlibpath + addr); 4600Sstevel@tonic-gate 4610Sstevel@tonic-gate if (crle->c_flags & CRLE_UPDATE) { 4620Sstevel@tonic-gate crle->c_flags &= ~CRLE_AOUT; 4630Sstevel@tonic-gate 4640Sstevel@tonic-gate #ifndef SGS_PRE_UNIFIED_PROCESS 4650Sstevel@tonic-gate if ((head->ch_cnflags & RTC_HDR_UPM) == 0) { 4660Sstevel@tonic-gate if (head->ch_cnflags & RTC_HDR_64) 4671618Srie str = conv_config_upm(str, 4680Sstevel@tonic-gate MSG_ORIG(MSG_PTH_OLDDLP_64), 4690Sstevel@tonic-gate MSG_ORIG(MSG_PTH_UPDLP_64), 4700Sstevel@tonic-gate MSG_PTH_UPDLP_64_SIZE); 4710Sstevel@tonic-gate else 4721618Srie str = conv_config_upm(str, 4730Sstevel@tonic-gate MSG_ORIG(MSG_PTH_OLDDLP), 4740Sstevel@tonic-gate MSG_ORIG(MSG_PTH_UPDLP), 4750Sstevel@tonic-gate MSG_PTH_UPDLP_SIZE); 4760Sstevel@tonic-gate } 4770Sstevel@tonic-gate #endif 4780Sstevel@tonic-gate if (addlib(crle, &crle->c_edlibpath, str) != 0) 4791976Sab196087 return (INSCFG_RET_FAIL); 4800Sstevel@tonic-gate } else { 4810Sstevel@tonic-gate (void) printf(MSG_INTL(MSG_DMP_DLIBPTH), 4820Sstevel@tonic-gate MSG_ORIG(MSG_STR_ELF), str); 4830Sstevel@tonic-gate 4840Sstevel@tonic-gate (void) snprintf(_cmd, PATH_MAX, 4850Sstevel@tonic-gate MSG_ORIG(MSG_CMD_EDLIB), str); 4860Sstevel@tonic-gate cmd = strcpy(alloca(strlen(_cmd) + 1), _cmd); 4870Sstevel@tonic-gate if (list_append(&cmdline, cmd) == 0) 4881976Sab196087 return (INSCFG_RET_FAIL); 4890Sstevel@tonic-gate } 4900Sstevel@tonic-gate } else { 4910Sstevel@tonic-gate if (crle->c_flags & CRLE_UPDATE) { 4920Sstevel@tonic-gate if (crle->c_flags & CRLE_EDLIB) { 4930Sstevel@tonic-gate /* 4940Sstevel@tonic-gate * If we've been asked to update a configuration 4950Sstevel@tonic-gate * file, and no existing default ELF search 4960Sstevel@tonic-gate * path exists, but the user is going to add new 4970Sstevel@tonic-gate * entries, fabricate the system defaults so 4980Sstevel@tonic-gate * that the users get added to them. 4990Sstevel@tonic-gate */ 5000Sstevel@tonic-gate if (fablib(crle, CRLE_EDLIB) != 0) 5011976Sab196087 return (INSCFG_RET_FAIL); 5020Sstevel@tonic-gate } 5030Sstevel@tonic-gate } else { 5040Sstevel@tonic-gate /* 5050Sstevel@tonic-gate * Indicate any system default. 5060Sstevel@tonic-gate */ 5071976Sab196087 #if M_CLASS == ELFCLASS64 5080Sstevel@tonic-gate #ifndef SGS_PRE_UNIFIED_PROCESS 5091976Sab196087 (void) printf(MSG_INTL(MSG_DEF_NEWDLP_64)); 5100Sstevel@tonic-gate #else 5111976Sab196087 (void) printf(MSG_INTL(MSG_DEF_OLDDLP_64)); 5120Sstevel@tonic-gate #endif 5131976Sab196087 #else 5140Sstevel@tonic-gate #ifndef SGS_PRE_UNIFIED_PROCESS 5151976Sab196087 (void) printf(MSG_INTL(MSG_DEF_NEWDLP)); 5160Sstevel@tonic-gate #else 5171976Sab196087 (void) printf(MSG_INTL(MSG_DEF_OLDDLP)); 5180Sstevel@tonic-gate #endif 5191976Sab196087 #endif 5200Sstevel@tonic-gate } 5210Sstevel@tonic-gate } 5220Sstevel@tonic-gate 5230Sstevel@tonic-gate if (head->ch_eslibpath) { 5240Sstevel@tonic-gate const char *str; 5250Sstevel@tonic-gate 5260Sstevel@tonic-gate str = (const char *)(head->ch_eslibpath + addr); 5270Sstevel@tonic-gate 5280Sstevel@tonic-gate if (crle->c_flags & CRLE_UPDATE) { 5290Sstevel@tonic-gate crle->c_flags &= ~CRLE_AOUT; 5300Sstevel@tonic-gate 5310Sstevel@tonic-gate #ifndef SGS_PRE_UNIFIED_PROCESS 5320Sstevel@tonic-gate if ((head->ch_cnflags & RTC_HDR_UPM) == 0) { 5330Sstevel@tonic-gate if (head->ch_cnflags & RTC_HDR_64) 5341618Srie str = conv_config_upm(str, 5350Sstevel@tonic-gate MSG_ORIG(MSG_PTH_OLDTD_64), 5360Sstevel@tonic-gate MSG_ORIG(MSG_PTH_UPTD_64), 5370Sstevel@tonic-gate MSG_PTH_UPTD_64_SIZE); 5380Sstevel@tonic-gate else 5391618Srie str = conv_config_upm(str, 5400Sstevel@tonic-gate MSG_ORIG(MSG_PTH_OLDTD), 5410Sstevel@tonic-gate MSG_ORIG(MSG_PTH_UPTD), 5420Sstevel@tonic-gate MSG_PTH_UPTD_SIZE); 5430Sstevel@tonic-gate } 5440Sstevel@tonic-gate #endif 5450Sstevel@tonic-gate if (addlib(crle, &crle->c_eslibpath, str) != 0) 5461976Sab196087 return (INSCFG_RET_FAIL); 5470Sstevel@tonic-gate } else { 5480Sstevel@tonic-gate (void) printf(MSG_INTL(MSG_DMP_TLIBPTH), 5490Sstevel@tonic-gate MSG_ORIG(MSG_STR_ELF), str); 5500Sstevel@tonic-gate 5510Sstevel@tonic-gate (void) snprintf(_cmd, PATH_MAX, 5520Sstevel@tonic-gate MSG_ORIG(MSG_CMD_ESLIB), str); 5530Sstevel@tonic-gate cmd = strcpy(alloca(strlen(_cmd) + 1), _cmd); 5540Sstevel@tonic-gate if (list_append(&cmdline, cmd) == 0) 5551976Sab196087 return (INSCFG_RET_FAIL); 5560Sstevel@tonic-gate } 5570Sstevel@tonic-gate } else { 5580Sstevel@tonic-gate if (crle->c_flags & CRLE_UPDATE) { 5590Sstevel@tonic-gate if (crle->c_flags & CRLE_ESLIB) { 5600Sstevel@tonic-gate /* 5610Sstevel@tonic-gate * If we've been asked to update a configuration 5620Sstevel@tonic-gate * file, and no existing default ELF secure 5630Sstevel@tonic-gate * path exists, but the user is going to add new 5640Sstevel@tonic-gate * entries, fabricate the system defaults so 5650Sstevel@tonic-gate * that the users get added to them. 5660Sstevel@tonic-gate */ 5670Sstevel@tonic-gate if (fablib(crle, CRLE_ESLIB) != 0) 5681976Sab196087 return (INSCFG_RET_FAIL); 5690Sstevel@tonic-gate } 5700Sstevel@tonic-gate } else { 5710Sstevel@tonic-gate /* 5720Sstevel@tonic-gate * Indicate any system default. 5730Sstevel@tonic-gate */ 5741976Sab196087 #if M_CLASS == ELFCLASS64 5750Sstevel@tonic-gate #ifndef SGS_PRE_UNIFIED_PROCESS 5761976Sab196087 (void) printf(MSG_INTL(MSG_DEF_NEWTD_64)); 5770Sstevel@tonic-gate #else 5781976Sab196087 (void) printf(MSG_INTL(MSG_DEF_OLDTD_64)); 5790Sstevel@tonic-gate #endif 5801976Sab196087 #else 5810Sstevel@tonic-gate #ifndef SGS_PRE_UNIFIED_PROCESS 5821976Sab196087 (void) printf(MSG_INTL(MSG_DEF_NEWTD)); 5830Sstevel@tonic-gate #else 5841976Sab196087 (void) printf(MSG_INTL(MSG_DEF_OLDTD)); 5850Sstevel@tonic-gate #endif 5861976Sab196087 #endif 5870Sstevel@tonic-gate } 5880Sstevel@tonic-gate } 5890Sstevel@tonic-gate 5900Sstevel@tonic-gate if (head->ch_adlibpath) { 5910Sstevel@tonic-gate const char *str; 5920Sstevel@tonic-gate 5930Sstevel@tonic-gate str = (const char *)(head->ch_adlibpath + addr); 5940Sstevel@tonic-gate 5950Sstevel@tonic-gate if (crle->c_flags & CRLE_UPDATE) { 5960Sstevel@tonic-gate crle->c_flags |= CRLE_AOUT; 5970Sstevel@tonic-gate if (addlib(crle, &crle->c_adlibpath, str) != 0) 5981976Sab196087 return (INSCFG_RET_FAIL); 5990Sstevel@tonic-gate } else { 6000Sstevel@tonic-gate (void) printf(MSG_INTL(MSG_DMP_DLIBPTH), 6010Sstevel@tonic-gate MSG_ORIG(MSG_STR_AOUT), str); 6020Sstevel@tonic-gate 6030Sstevel@tonic-gate (void) snprintf(_cmd, PATH_MAX, 6040Sstevel@tonic-gate MSG_ORIG(MSG_CMD_ADLIB), str); 6050Sstevel@tonic-gate cmd = strcpy(alloca(strlen(_cmd) + 1), _cmd); 6060Sstevel@tonic-gate if (list_append(&cmdline, cmd) == 0) 6071976Sab196087 return (INSCFG_RET_FAIL); 6080Sstevel@tonic-gate } 6090Sstevel@tonic-gate } else { 6100Sstevel@tonic-gate if (crle->c_flags & CRLE_UPDATE) { 6110Sstevel@tonic-gate if (crle->c_flags & CRLE_ADLIB) { 6120Sstevel@tonic-gate /* 6130Sstevel@tonic-gate * If we've been asked to update a configuration 6140Sstevel@tonic-gate * file, and no existing default AOUT search 6150Sstevel@tonic-gate * path exists, but the user is going to add new 6160Sstevel@tonic-gate * entries, fabricate the system defaults so 6170Sstevel@tonic-gate * that the users get added to them. 6180Sstevel@tonic-gate */ 6190Sstevel@tonic-gate if (fablib(crle, CRLE_ADLIB) != 0) 6201976Sab196087 return (INSCFG_RET_FAIL); 6210Sstevel@tonic-gate } 6220Sstevel@tonic-gate } else if (crle->c_flags & CRLE_AOUT) { 6230Sstevel@tonic-gate /* 6240Sstevel@tonic-gate * Indicate any system default. 6250Sstevel@tonic-gate */ 6260Sstevel@tonic-gate (void) printf(MSG_INTL(MSG_DEF_AOUTDLP)); 6270Sstevel@tonic-gate } 6280Sstevel@tonic-gate } 6290Sstevel@tonic-gate 6300Sstevel@tonic-gate if (head->ch_aslibpath) { 6310Sstevel@tonic-gate const char *str; 6320Sstevel@tonic-gate 6330Sstevel@tonic-gate str = (const char *)(head->ch_aslibpath + addr); 6340Sstevel@tonic-gate 6350Sstevel@tonic-gate if (crle->c_flags & CRLE_UPDATE) { 6360Sstevel@tonic-gate crle->c_flags |= CRLE_AOUT; 6370Sstevel@tonic-gate if (addlib(crle, &crle->c_aslibpath, str) != 0) 6381976Sab196087 return (INSCFG_RET_FAIL); 6390Sstevel@tonic-gate } else { 6400Sstevel@tonic-gate (void) printf(MSG_INTL(MSG_DMP_TLIBPTH), 6410Sstevel@tonic-gate MSG_ORIG(MSG_STR_AOUT), str); 6420Sstevel@tonic-gate 6430Sstevel@tonic-gate (void) snprintf(_cmd, PATH_MAX, 6440Sstevel@tonic-gate MSG_ORIG(MSG_CMD_ASLIB), str); 6450Sstevel@tonic-gate cmd = strcpy(alloca(strlen(_cmd) + 1), _cmd); 6460Sstevel@tonic-gate if (list_append(&cmdline, cmd) == 0) 6471976Sab196087 return (INSCFG_RET_FAIL); 6480Sstevel@tonic-gate } 6490Sstevel@tonic-gate } else { 6500Sstevel@tonic-gate if (crle->c_flags & CRLE_UPDATE) { 6510Sstevel@tonic-gate if (crle->c_flags & CRLE_ASLIB) { 6520Sstevel@tonic-gate /* 6530Sstevel@tonic-gate * If we've been asked to update a configuration 6540Sstevel@tonic-gate * file, and no existing default AOUT secure 6550Sstevel@tonic-gate * path exists, but the user is going to add new 6560Sstevel@tonic-gate * entries, fabricate the system defaults so 6570Sstevel@tonic-gate * that the users get added to them. 6580Sstevel@tonic-gate */ 6590Sstevel@tonic-gate if (fablib(crle, CRLE_ASLIB) != 0) 6601976Sab196087 return (INSCFG_RET_FAIL); 6610Sstevel@tonic-gate } 6620Sstevel@tonic-gate } else if (crle->c_flags & CRLE_AOUT) { 6630Sstevel@tonic-gate /* 6640Sstevel@tonic-gate * Indicate any system default. 6650Sstevel@tonic-gate */ 6660Sstevel@tonic-gate (void) printf(MSG_INTL(MSG_DEF_AOUTTD)); 6670Sstevel@tonic-gate } 6680Sstevel@tonic-gate } 6690Sstevel@tonic-gate 6700Sstevel@tonic-gate /* 6710Sstevel@tonic-gate * Display any environment variables. 6720Sstevel@tonic-gate */ 6730Sstevel@tonic-gate if ((head->ch_version >= RTC_VER_THREE) && head->ch_env) { 6740Sstevel@tonic-gate Rtc_env * envtbl; 6750Sstevel@tonic-gate 6760Sstevel@tonic-gate if ((crle->c_flags & CRLE_UPDATE) == 0) 6770Sstevel@tonic-gate (void) printf(MSG_INTL(MSG_ENV_TITLE)); 6780Sstevel@tonic-gate 6790Sstevel@tonic-gate for (envtbl = (Rtc_env *)(head->ch_env + addr); 6800Sstevel@tonic-gate envtbl->env_str; envtbl++) { 6810Sstevel@tonic-gate const char *str; 6820Sstevel@tonic-gate 6830Sstevel@tonic-gate str = (const char *)(envtbl->env_str + addr); 6840Sstevel@tonic-gate 6850Sstevel@tonic-gate if (crle->c_flags & CRLE_UPDATE) { 6860Sstevel@tonic-gate if (addenv(crle, str, 6870Sstevel@tonic-gate (envtbl->env_flags | RTC_ENV_CONFIG)) == 0) 6881976Sab196087 return (INSCFG_RET_FAIL); 6890Sstevel@tonic-gate } else { 6900Sstevel@tonic-gate const char *pfmt, *sfmt; 6910Sstevel@tonic-gate 6920Sstevel@tonic-gate if (envtbl->env_flags & RTC_ENV_PERMANT) { 6930Sstevel@tonic-gate pfmt = MSG_INTL(MSG_ENV_PRM); 6940Sstevel@tonic-gate sfmt = MSG_ORIG(MSG_CMD_PRMENV); 6950Sstevel@tonic-gate } else { 6960Sstevel@tonic-gate pfmt = MSG_INTL(MSG_ENV_RPL); 6970Sstevel@tonic-gate sfmt = MSG_ORIG(MSG_CMD_RPLENV); 6980Sstevel@tonic-gate } 6990Sstevel@tonic-gate (void) printf(pfmt, str); 7000Sstevel@tonic-gate (void) snprintf(_cmd, PATH_MAX, sfmt, str); 7010Sstevel@tonic-gate cmd = strcpy(alloca(strlen(_cmd) + 1), _cmd); 7020Sstevel@tonic-gate if (list_append(&cmdline, cmd) == 0) 7031976Sab196087 return (INSCFG_RET_FAIL); 7040Sstevel@tonic-gate } 7050Sstevel@tonic-gate } 7060Sstevel@tonic-gate } 7070Sstevel@tonic-gate 7080Sstevel@tonic-gate /* 7090Sstevel@tonic-gate * Display any filter/filtee associations. 7100Sstevel@tonic-gate */ 7110Sstevel@tonic-gate if ((head->ch_version >= RTC_VER_FOUR) && head->ch_fltr) { 7120Sstevel@tonic-gate if ((crle->c_flags & CRLE_UPDATE) == 0) { 7130Sstevel@tonic-gate Rtc_fltr * fltrtbl; 7140Sstevel@tonic-gate Rtc_flte * fltetbl; 7150Sstevel@tonic-gate 7160Sstevel@tonic-gate /* LINTED */ 7171976Sab196087 fltrtbl = (Rtc_fltr *) 718*4734Sab196087 (CAST_PTRINT(char *, head->ch_fltr) + addr); 7190Sstevel@tonic-gate /* LINTED */ 7201976Sab196087 fltetbl = (Rtc_flte *) 721*4734Sab196087 (CAST_PTRINT(char *, head->ch_flte) + addr); 7220Sstevel@tonic-gate 7230Sstevel@tonic-gate (void) printf(MSG_INTL(MSG_FLT_TITLE)); 7240Sstevel@tonic-gate 7250Sstevel@tonic-gate while (fltrtbl->fr_filter) { 7260Sstevel@tonic-gate Rtc_flte *_fltetbl; 7270Sstevel@tonic-gate 7280Sstevel@tonic-gate /* 7290Sstevel@tonic-gate * Print the filter and filtee string pair. 7300Sstevel@tonic-gate */ 7310Sstevel@tonic-gate (void) printf(MSG_INTL(MSG_FLT_FILTER), 7320Sstevel@tonic-gate (strtbl + fltrtbl->fr_filter), 7330Sstevel@tonic-gate (strtbl + fltrtbl->fr_string)); 7340Sstevel@tonic-gate 7350Sstevel@tonic-gate /* 7360Sstevel@tonic-gate * Print each filtee. 7370Sstevel@tonic-gate */ 7380Sstevel@tonic-gate /* LINTED */ 7390Sstevel@tonic-gate for (_fltetbl = (Rtc_flte *)((char *)fltetbl + 7400Sstevel@tonic-gate fltrtbl->fr_filtee); _fltetbl->fe_filtee; 7410Sstevel@tonic-gate _fltetbl++) { 7420Sstevel@tonic-gate (void) printf(MSG_INTL(MSG_FLT_FILTEE), 7430Sstevel@tonic-gate (strtbl + _fltetbl->fe_filtee)); 7440Sstevel@tonic-gate } 7450Sstevel@tonic-gate fltrtbl++; 7460Sstevel@tonic-gate } 7470Sstevel@tonic-gate } 7480Sstevel@tonic-gate } 7490Sstevel@tonic-gate 7500Sstevel@tonic-gate /* 7510Sstevel@tonic-gate * Display any memory reservations required for any alternative 7520Sstevel@tonic-gate * objects. 7530Sstevel@tonic-gate */ 7540Sstevel@tonic-gate if (head->ch_resbgn && ((crle->c_flags & CRLE_UPDATE) == 0)) 7552056Sab196087 (void) printf(MSG_INTL(MSG_DMP_RESV), 756*4734Sab196087 (u_longlong_t)head->ch_resbgn, 757*4734Sab196087 (u_longlong_t)head->ch_resend, 758*4734Sab196087 (u_longlong_t)(head->ch_resend - head->ch_resbgn)); 7590Sstevel@tonic-gate 7600Sstevel@tonic-gate /* 7610Sstevel@tonic-gate * If there's no hash table there's nothing else to process. 7620Sstevel@tonic-gate */ 7630Sstevel@tonic-gate if (head->ch_hash == 0) { 7640Sstevel@tonic-gate if ((crle->c_flags & CRLE_UPDATE) == 0) 7650Sstevel@tonic-gate printcmd(crle, head, &cmdline); 7661976Sab196087 return (INSCFG_RET_OK); 7670Sstevel@tonic-gate } 7680Sstevel@tonic-gate 7690Sstevel@tonic-gate /* 7700Sstevel@tonic-gate * Traverse the directory and filename arrays. 7710Sstevel@tonic-gate */ 7720Sstevel@tonic-gate for (dirtbl = (Rtc_dir *)(head->ch_dir + addr); 7730Sstevel@tonic-gate dirtbl->cd_obj; dirtbl++) { 7740Sstevel@tonic-gate struct stat status; 7750Sstevel@tonic-gate Rtc_obj *dobj; 7760Sstevel@tonic-gate const char *str; 7770Sstevel@tonic-gate 7780Sstevel@tonic-gate dobj = (Rtc_obj *)(dirtbl->cd_obj + addr); 7790Sstevel@tonic-gate filetbl = (Rtc_file *)(dirtbl->cd_file + addr); 7800Sstevel@tonic-gate str = strtbl + dobj->co_name; 7810Sstevel@tonic-gate 7820Sstevel@tonic-gate /* 7830Sstevel@tonic-gate * Simplify recreation by using any command-line directories. 7840Sstevel@tonic-gate * If we're dealing with a version 1 configuration file use 7850Sstevel@tonic-gate * every directory. 7860Sstevel@tonic-gate */ 7870Sstevel@tonic-gate if ((dobj->co_flags & RTC_OBJ_CMDLINE) || 7880Sstevel@tonic-gate (head->ch_version == RTC_VER_ONE)) { 7890Sstevel@tonic-gate if (crle->c_flags & CRLE_UPDATE) { 7900Sstevel@tonic-gate if (inspect(crle, str, 7910Sstevel@tonic-gate getflags(dobj->co_flags)) != 0) 7921976Sab196087 return (INSCFG_RET_FAIL); 7930Sstevel@tonic-gate if ((dobj->co_flags & 7940Sstevel@tonic-gate (RTC_OBJ_NOEXIST | RTC_OBJ_ALTER)) == 7950Sstevel@tonic-gate RTC_OBJ_NOEXIST) 7960Sstevel@tonic-gate continue; 7970Sstevel@tonic-gate } else { 7980Sstevel@tonic-gate /* LINTED */ 7990Sstevel@tonic-gate (void) snprintf(_cmd, PATH_MAX, 8000Sstevel@tonic-gate getformat(dobj->co_flags), str); 8010Sstevel@tonic-gate cmd = strcpy(alloca(strlen(_cmd) + 1), _cmd); 8020Sstevel@tonic-gate if (list_append(&cmdline, cmd) == 0) 8031976Sab196087 return (INSCFG_RET_FAIL); 8040Sstevel@tonic-gate } 8050Sstevel@tonic-gate } 8060Sstevel@tonic-gate 8070Sstevel@tonic-gate /* 8080Sstevel@tonic-gate * If this isn't an update print the directory name. If the 8090Sstevel@tonic-gate * directory has no entries (possible if the directory is a 8100Sstevel@tonic-gate * symlink to another directory, in which case we record the 8110Sstevel@tonic-gate * real path also), don't bother printing it unless we're in 8120Sstevel@tonic-gate * verbose mode. 8130Sstevel@tonic-gate */ 8140Sstevel@tonic-gate if ((crle->c_flags & CRLE_UPDATE) == 0) { 8150Sstevel@tonic-gate if ((dobj->co_flags & 8160Sstevel@tonic-gate (RTC_OBJ_NOEXIST | RTC_OBJ_ALTER)) == 8170Sstevel@tonic-gate RTC_OBJ_NOEXIST) { 8180Sstevel@tonic-gate (void) printf(MSG_INTL(MSG_DMP_DIR_2), str); 8190Sstevel@tonic-gate continue; 8200Sstevel@tonic-gate } else if (filetbl->cf_obj || 8210Sstevel@tonic-gate (crle->c_flags & CRLE_VERBOSE)) 8220Sstevel@tonic-gate (void) printf(MSG_INTL(MSG_DMP_DIR_1), str); 8230Sstevel@tonic-gate } 8240Sstevel@tonic-gate 8250Sstevel@tonic-gate /* 8260Sstevel@tonic-gate * Under verbose mode validate any real directory entry - the 8270Sstevel@tonic-gate * same test will be carried out by ld.so.1. 8280Sstevel@tonic-gate */ 8290Sstevel@tonic-gate if (((crle->c_flags & CRLE_UPDATE) == 0) && 8300Sstevel@tonic-gate (crle->c_flags & CRLE_VERBOSE) && 8310Sstevel@tonic-gate (dobj->co_flags & RTC_OBJ_REALPTH)) { 8320Sstevel@tonic-gate if (stat(str, &status) != 0) { 8330Sstevel@tonic-gate int err = errno; 8340Sstevel@tonic-gate (void) printf(MSG_INTL(MSG_DMP_STAT), str, 8350Sstevel@tonic-gate strerror(err)); 8360Sstevel@tonic-gate } else if (status.st_mtime != dobj->co_info) { 8370Sstevel@tonic-gate (void) printf(MSG_INTL(MSG_DMP_DCMP), str); 8380Sstevel@tonic-gate } 8390Sstevel@tonic-gate } 8400Sstevel@tonic-gate 8410Sstevel@tonic-gate for (; filetbl->cf_obj; filetbl++) { 8420Sstevel@tonic-gate Rtc_obj * fobj; 8430Sstevel@tonic-gate Half flags; 8440Sstevel@tonic-gate 8450Sstevel@tonic-gate fobj = (Rtc_obj *)(filetbl->cf_obj + addr); 8460Sstevel@tonic-gate str = strtbl + fobj->co_name; 8470Sstevel@tonic-gate flags = fobj->co_flags; 8480Sstevel@tonic-gate 8490Sstevel@tonic-gate /* 8500Sstevel@tonic-gate * Only update individual files that were originally 8510Sstevel@tonic-gate * specified on the command-line. Or, if this is a 8520Sstevel@tonic-gate * version 1 configuration file use every file that 8530Sstevel@tonic-gate * isn't part of an all-entries directory. 8540Sstevel@tonic-gate */ 8550Sstevel@tonic-gate if (((flags & RTC_OBJ_CMDLINE) && 8560Sstevel@tonic-gate ((fobj->co_flags & RTC_OBJ_APP) == 0)) || 8570Sstevel@tonic-gate ((head->ch_version == RTC_VER_ONE) && 8580Sstevel@tonic-gate ((dobj->co_flags & RTC_OBJ_ALLENTS) == 0))) { 8590Sstevel@tonic-gate char *alter = 0, altdir[PATH_MAX]; 8600Sstevel@tonic-gate 8610Sstevel@tonic-gate /* 8620Sstevel@tonic-gate * Determine whether this file requires an 8630Sstevel@tonic-gate * alternative, and if so, and we haven't 8640Sstevel@tonic-gate * already an alternative in affect, create one. 8650Sstevel@tonic-gate */ 8660Sstevel@tonic-gate if (fobj->co_flags & RTC_OBJ_ALTER) { 8670Sstevel@tonic-gate alter = (char *)(strtbl + 8680Sstevel@tonic-gate fobj->co_alter); 8690Sstevel@tonic-gate (void) strcpy(altdir, alter); 8700Sstevel@tonic-gate alter = strrchr(altdir, '/'); 8710Sstevel@tonic-gate *alter = '\0'; 8720Sstevel@tonic-gate 8730Sstevel@tonic-gate if ((objdir == 0) || 8740Sstevel@tonic-gate (strcmp(objdir, altdir) != 0)) { 8750Sstevel@tonic-gate (void) strcpy(_objdir, altdir); 8760Sstevel@tonic-gate crle->c_objdir = alter = 8770Sstevel@tonic-gate objdir = _objdir; 8780Sstevel@tonic-gate } else 8790Sstevel@tonic-gate alter = 0; 8800Sstevel@tonic-gate } 8810Sstevel@tonic-gate 8820Sstevel@tonic-gate if (crle->c_flags & CRLE_UPDATE) { 8830Sstevel@tonic-gate if (inspect(crle, str, 8840Sstevel@tonic-gate getflags(flags)) != 0) 8851976Sab196087 return (INSCFG_RET_FAIL); 8860Sstevel@tonic-gate continue; 8870Sstevel@tonic-gate } 8880Sstevel@tonic-gate 8890Sstevel@tonic-gate if (alter) { 8900Sstevel@tonic-gate (void) snprintf(_cmd, PATH_MAX, 8910Sstevel@tonic-gate MSG_ORIG(MSG_CMD_OUTPUT), 8920Sstevel@tonic-gate crle->c_objdir); 8930Sstevel@tonic-gate cmd = strcpy(alloca(strlen(_cmd) + 1), 8940Sstevel@tonic-gate _cmd); 8950Sstevel@tonic-gate if (list_append(&cmdline, cmd) == 0) 8961976Sab196087 return (INSCFG_RET_FAIL); 8970Sstevel@tonic-gate } 8980Sstevel@tonic-gate 8990Sstevel@tonic-gate /* LINTED */ 9000Sstevel@tonic-gate (void) snprintf(_cmd, PATH_MAX, 9010Sstevel@tonic-gate getformat(flags), str); 9020Sstevel@tonic-gate cmd = strcpy(alloca(strlen(_cmd) + 1), _cmd); 9030Sstevel@tonic-gate if (list_append(&cmdline, cmd) == 0) 9041976Sab196087 return (INSCFG_RET_FAIL); 9050Sstevel@tonic-gate } 9060Sstevel@tonic-gate 9070Sstevel@tonic-gate if (crle->c_flags & CRLE_UPDATE) 9080Sstevel@tonic-gate continue; 9090Sstevel@tonic-gate 9100Sstevel@tonic-gate /* 9110Sstevel@tonic-gate * Although we record both full pathnames and their 9120Sstevel@tonic-gate * simple filenames (basename), only print the simple 9130Sstevel@tonic-gate * names unless we're under verbose mode. 9140Sstevel@tonic-gate */ 9150Sstevel@tonic-gate if ((strchr(str, '/') == 0) || 9160Sstevel@tonic-gate (crle->c_flags & CRLE_VERBOSE)) { 9170Sstevel@tonic-gate if (fobj->co_flags & RTC_OBJ_ALTER) 9180Sstevel@tonic-gate (void) printf(MSG_INTL(MSG_DMP_FILE_2), 9190Sstevel@tonic-gate str, (strtbl + fobj->co_alter)); 9200Sstevel@tonic-gate else 9210Sstevel@tonic-gate (void) printf(MSG_INTL(MSG_DMP_FILE_1), 9220Sstevel@tonic-gate str); 9230Sstevel@tonic-gate } 9240Sstevel@tonic-gate 9250Sstevel@tonic-gate /* 9260Sstevel@tonic-gate * Under verbose mode validate any real file entry - the 9270Sstevel@tonic-gate * same test will be carried out by ld.so.1. 9280Sstevel@tonic-gate */ 9290Sstevel@tonic-gate if ((crle->c_flags & CRLE_VERBOSE) && 9300Sstevel@tonic-gate (fobj->co_flags & RTC_OBJ_REALPTH)) { 9310Sstevel@tonic-gate if (stat(str, &status) != 0) { 9320Sstevel@tonic-gate int err = errno; 9330Sstevel@tonic-gate (void) printf(MSG_INTL(MSG_DMP_STAT), 9340Sstevel@tonic-gate str, strerror(err)); 9350Sstevel@tonic-gate } else if (status.st_size != fobj->co_info) { 9360Sstevel@tonic-gate (void) printf(MSG_INTL(MSG_DMP_FCMP), 9370Sstevel@tonic-gate str); 9380Sstevel@tonic-gate } 9390Sstevel@tonic-gate } 9400Sstevel@tonic-gate } 9410Sstevel@tonic-gate } 9420Sstevel@tonic-gate 9430Sstevel@tonic-gate if ((crle->c_flags & CRLE_UPDATE) == 0) 9440Sstevel@tonic-gate printcmd(crle, head, &cmdline); 9450Sstevel@tonic-gate 9460Sstevel@tonic-gate if ((crle->c_flags & CRLE_VERBOSE) == 0) 9471976Sab196087 return (INSCFG_RET_OK); 9480Sstevel@tonic-gate 9490Sstevel@tonic-gate /* 9500Sstevel@tonic-gate * If we've in verbose mode scan the hash list. 9510Sstevel@tonic-gate */ 9520Sstevel@tonic-gate /* LINTED */ 9531976Sab196087 hash = (Word *)(CAST_PTRINT(char *, head->ch_hash) + addr); 9540Sstevel@tonic-gate bkts = hash[0]; 9550Sstevel@tonic-gate chain = &hash[2 + bkts]; 9560Sstevel@tonic-gate hash += 2; 9570Sstevel@tonic-gate 9580Sstevel@tonic-gate (void) printf(MSG_INTL(MSG_DMP_HASH)); 9590Sstevel@tonic-gate 9600Sstevel@tonic-gate /* 9610Sstevel@tonic-gate * Scan the hash buckets looking for valid entries. 9620Sstevel@tonic-gate */ 9630Sstevel@tonic-gate for (ndx = 0; ndx < bkts; ndx++, hash++) { 964*4734Sab196087 Conv_config_obj_buf_t config_obj_buf; 965*4734Sab196087 Rtc_obj *obj; 966*4734Sab196087 const char *str; 967*4734Sab196087 Word _ndx; 9680Sstevel@tonic-gate 9690Sstevel@tonic-gate if (*hash == 0) 9700Sstevel@tonic-gate continue; 9710Sstevel@tonic-gate 9720Sstevel@tonic-gate obj = objtbl + *hash; 9730Sstevel@tonic-gate str = strtbl + obj->co_name; 9740Sstevel@tonic-gate 9750Sstevel@tonic-gate (void) printf(MSG_INTL(MSG_DMP_HASHENT_1), obj->co_id, ndx, 976*4734Sab196087 str, conv_config_obj(obj->co_flags, &config_obj_buf)); 9770Sstevel@tonic-gate 9780Sstevel@tonic-gate /* 9790Sstevel@tonic-gate * Determine whether there are other objects chained to this 9800Sstevel@tonic-gate * bucket. 9810Sstevel@tonic-gate */ 9820Sstevel@tonic-gate for (_ndx = chain[*hash]; _ndx; _ndx = chain[_ndx]) { 9830Sstevel@tonic-gate obj = objtbl + _ndx; 9840Sstevel@tonic-gate str = strtbl + obj->co_name; 9850Sstevel@tonic-gate 9860Sstevel@tonic-gate (void) printf(MSG_INTL(MSG_DMP_HASHENT_2), obj->co_id, 987*4734Sab196087 str, conv_config_obj(obj->co_flags, 988*4734Sab196087 &config_obj_buf)); 9890Sstevel@tonic-gate } 9900Sstevel@tonic-gate } 9910Sstevel@tonic-gate (void) printf(MSG_ORIG(MSG_STR_NL)); 9920Sstevel@tonic-gate 9931976Sab196087 return (INSCFG_RET_OK); 9940Sstevel@tonic-gate } 9950Sstevel@tonic-gate 9960Sstevel@tonic-gate 9971976Sab196087 INSCFG_RET 9982056Sab196087 inspectconfig(Crle_desc * crle, int c_class) 9990Sstevel@tonic-gate { 10001976Sab196087 INSCFG_RET error; 10011976Sab196087 int fd; 10020Sstevel@tonic-gate Addr addr; 10030Sstevel@tonic-gate struct stat status; 10040Sstevel@tonic-gate const char *caller = crle->c_name, *file = crle->c_confil; 1005*4734Sab196087 Conv_inv_buf_t inv_buf1, inv_buf2, inv_buf3; 10060Sstevel@tonic-gate 10070Sstevel@tonic-gate /* 10080Sstevel@tonic-gate * Open the configuration file, determine its size and map it in. 10090Sstevel@tonic-gate */ 10100Sstevel@tonic-gate if ((fd = open(file, O_RDONLY, 0)) == -1) { 10110Sstevel@tonic-gate int err = errno; 10120Sstevel@tonic-gate 10132056Sab196087 if (err == ENOENT) { 10142056Sab196087 #ifndef _ELF64 10152056Sab196087 /* Must restart if user requested a 64-bit file */ 10162056Sab196087 if (c_class == ELFCLASS64) 10172056Sab196087 return (INSCFG_RET_NEED64); 10182056Sab196087 #endif 10192056Sab196087 10200Sstevel@tonic-gate /* 10210Sstevel@tonic-gate * To allow an update (-u) from scratch, fabricate any 10220Sstevel@tonic-gate * default search and secure paths that the user 10230Sstevel@tonic-gate * intends to add to. 10240Sstevel@tonic-gate */ 10250Sstevel@tonic-gate if (crle->c_flags & CRLE_UPDATE) { 10260Sstevel@tonic-gate if (crle->c_flags & CRLE_EDLIB) { 10270Sstevel@tonic-gate if (fablib(crle, CRLE_EDLIB)) 10282056Sab196087 return (INSCFG_RET_FAIL); 10290Sstevel@tonic-gate } 10300Sstevel@tonic-gate if (crle->c_flags & CRLE_ESLIB) { 10310Sstevel@tonic-gate if (fablib(crle, CRLE_ESLIB)) 10322056Sab196087 return (INSCFG_RET_FAIL); 10330Sstevel@tonic-gate } 10340Sstevel@tonic-gate if (crle->c_flags & CRLE_ADLIB) { 10350Sstevel@tonic-gate if (fablib(crle, CRLE_ADLIB)) 10362056Sab196087 return (INSCFG_RET_FAIL); 10370Sstevel@tonic-gate } 10380Sstevel@tonic-gate if (crle->c_flags & CRLE_ASLIB) { 10390Sstevel@tonic-gate if (fablib(crle, CRLE_ASLIB)) 10402056Sab196087 return (INSCFG_RET_FAIL); 10410Sstevel@tonic-gate } 10422056Sab196087 return (INSCFG_RET_OK); 10430Sstevel@tonic-gate 10440Sstevel@tonic-gate } else if (crle->c_flags & CRLE_CONFDEF) { 10450Sstevel@tonic-gate const char *fmt1, *fmt2; 10460Sstevel@tonic-gate 10470Sstevel@tonic-gate /* 10480Sstevel@tonic-gate * Otherwise if the user is inspecting a default 10490Sstevel@tonic-gate * configuration file that doesn't exist inform 10500Sstevel@tonic-gate * them and display the ELF defaults. 10510Sstevel@tonic-gate */ 10520Sstevel@tonic-gate (void) printf(MSG_INTL(MSG_DEF_NOCONF), file); 10532056Sab196087 (void) printf(MSG_INTL(MSG_DMP_PLATFORM), 1054*4734Sab196087 conv_ehdr_class(M_CLASS, 1055*4734Sab196087 CONV_FMT_ALTFILE, &inv_buf1), 1056*4734Sab196087 conv_ehdr_data(M_DATA, 1057*4734Sab196087 CONV_FMT_ALTFILE, &inv_buf2), 1058*4734Sab196087 conv_ehdr_mach(M_MACH, 1059*4734Sab196087 CONV_FMT_ALTFILE, &inv_buf3)); 10602056Sab196087 10610Sstevel@tonic-gate 10620Sstevel@tonic-gate if (crle->c_flags & CRLE_AOUT) { 10630Sstevel@tonic-gate fmt1 = MSG_INTL(MSG_DEF_AOUTDLP); 10640Sstevel@tonic-gate fmt2 = MSG_INTL(MSG_DEF_AOUTTD); 10650Sstevel@tonic-gate } else { 10661976Sab196087 #if M_CLASS == ELFCLASS64 10670Sstevel@tonic-gate #ifndef SGS_PRE_UNIFIED_PROCESS 10681976Sab196087 fmt1 = MSG_INTL(MSG_DEF_NEWDLP_64); 10691976Sab196087 fmt2 = MSG_INTL(MSG_DEF_NEWTD_64); 10700Sstevel@tonic-gate #else 10711976Sab196087 fmt1 = MSG_INTL(MSG_DEF_OLDDLP_64); 10721976Sab196087 fmt2 = MSG_INTL(MSG_DEF_OLDTD_64); 10730Sstevel@tonic-gate #endif 10741976Sab196087 #else 10750Sstevel@tonic-gate #ifndef SGS_PRE_UNIFIED_PROCESS 10761976Sab196087 fmt1 = MSG_INTL(MSG_DEF_NEWDLP); 10771976Sab196087 fmt2 = MSG_INTL(MSG_DEF_NEWTD); 10780Sstevel@tonic-gate #else 10791976Sab196087 fmt1 = MSG_INTL(MSG_DEF_OLDDLP); 10801976Sab196087 fmt2 = MSG_INTL(MSG_DEF_OLDTD); 10810Sstevel@tonic-gate #endif 10821976Sab196087 #endif 10830Sstevel@tonic-gate } 10840Sstevel@tonic-gate (void) printf(fmt1); 10850Sstevel@tonic-gate (void) printf(fmt2); 10860Sstevel@tonic-gate 10872056Sab196087 return (INSCFG_RET_OK); 10880Sstevel@tonic-gate } 10890Sstevel@tonic-gate } 10900Sstevel@tonic-gate 10910Sstevel@tonic-gate /* 10920Sstevel@tonic-gate * Otherwise there's an error condition in accessing the file. 10930Sstevel@tonic-gate */ 10940Sstevel@tonic-gate (void) fprintf(stderr, MSG_INTL(MSG_SYS_OPEN), caller, file, 10950Sstevel@tonic-gate strerror(err)); 10960Sstevel@tonic-gate 10972056Sab196087 return (INSCFG_RET_FAIL); 10980Sstevel@tonic-gate } 10990Sstevel@tonic-gate 11000Sstevel@tonic-gate (void) fstat(fd, &status); 11010Sstevel@tonic-gate if (status.st_size < sizeof (Rtc_head)) { 11020Sstevel@tonic-gate (void) close(fd); 11030Sstevel@tonic-gate (void) fprintf(stderr, MSG_INTL(MSG_COR_TRUNC), caller, file); 11042056Sab196087 return (INSCFG_RET_FAIL); 11050Sstevel@tonic-gate } 11060Sstevel@tonic-gate if ((addr = (Addr)mmap(0, status.st_size, PROT_READ, MAP_SHARED, 11070Sstevel@tonic-gate fd, 0)) == (Addr)MAP_FAILED) { 11080Sstevel@tonic-gate int err = errno; 11090Sstevel@tonic-gate (void) fprintf(stderr, MSG_INTL(MSG_SYS_MMAP), caller, file, 11100Sstevel@tonic-gate strerror(err)); 11110Sstevel@tonic-gate (void) close(fd); 11122056Sab196087 return (INSCFG_RET_FAIL); 11130Sstevel@tonic-gate } 11140Sstevel@tonic-gate (void) close(fd); 11150Sstevel@tonic-gate 11160Sstevel@tonic-gate /* 11170Sstevel@tonic-gate * Print the contents of the configuration file. 11180Sstevel@tonic-gate */ 11192056Sab196087 error = scanconfig(crle, addr, c_class); 11200Sstevel@tonic-gate 11210Sstevel@tonic-gate (void) munmap((void *)addr, status.st_size); 11220Sstevel@tonic-gate return (error); 11230Sstevel@tonic-gate } 1124