Home | History | Annotate | Download | only in common
      1 /*
      2  * CDDL HEADER START
      3  *
      4  * The contents of this file are subject to the terms of the
      5  * Common Development and Distribution License (the "License").
      6  * You may not use this file except in compliance with the License.
      7  *
      8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9  * or http://www.opensolaris.org/os/licensing.
     10  * See the License for the specific language governing permissions
     11  * and limitations under the License.
     12  *
     13  * When distributing Covered Code, include this CDDL HEADER in each
     14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15  * If applicable, add the following below this CDDL HEADER, with the
     16  * fields enclosed by brackets "[]" replaced with your own identifying
     17  * information: Portions Copyright [yyyy] [name of copyright owner]
     18  *
     19  * CDDL HEADER END
     20  */
     21 
     22 /*
     23  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
     24  * Use is subject to license terms.
     25  */
     26 
     27 #include	<sys/auxv.h>
     28 #include	<string.h>
     29 #include	<unistd.h>
     30 #include	<fcntl.h>
     31 #include	<limits.h>
     32 #include	<stdio.h>
     33 #include	<libld.h>
     34 #include	<rtld.h>
     35 #include	<conv.h>
     36 #include	"msg.h"
     37 #include	"_debug.h"
     38 
     39 void
     40 Dbg_file_analyze(Rt_map *lmp)
     41 {
     42 	Conv_dl_mode_buf_t	dl_mode_buf;
     43 	Lm_list			*lml = LIST(lmp);
     44 
     45 	if (DBG_NOTCLASS(DBG_C_FILES))
     46 		return;
     47 
     48 	Dbg_util_nl(lml, DBG_NL_STD);
     49 	dbg_print(lml, MSG_INTL(MSG_FIL_ANALYZE), NAME(lmp),
     50 	    conv_dl_mode(MODE(lmp), 1, &dl_mode_buf));
     51 }
     52 
     53 void
     54 Dbg_file_mmapobj(Lm_list *lml, const char *name, mmapobj_result_t *ompp,
     55     uint_t onum)
     56 {
     57 	mmapobj_result_t	*mpp;
     58 	uint_t			mnum;
     59 
     60 	if (DBG_NOTCLASS(DBG_C_FILES))
     61 		return;
     62 	if (DBG_NOTDETAIL())
     63 		return;
     64 
     65 	Dbg_util_nl(lml, DBG_NL_STD);
     66 	dbg_print(lml, MSG_INTL(MSG_FIL_MMAPOBJ), name, onum);
     67 
     68 	for (mnum = 0, mpp = ompp; mnum < onum; mnum++, mpp++) {
     69 		const char	*str;
     70 		uint_t		type = MR_GET_TYPE(mpp->mr_flags);
     71 
     72 		if (type == MR_PADDING)
     73 			str = MSG_ORIG(MSG_MR_PADDING);
     74 		else if (type == MR_HDR_ELF)
     75 			str = MSG_ORIG(MSG_MR_HDR_ELF);
     76 		else if (type == MR_HDR_AOUT)
     77 			str = MSG_ORIG(MSG_MR_HDR_AOUT);
     78 		else
     79 			str = MSG_ORIG(MSG_STR_EMPTY);
     80 
     81 		dbg_print(lml, MSG_INTL(MSG_FIL_MMAPOBJ_1), mnum,
     82 		    EC_NATPTR(mpp->mr_addr), EC_OFF(mpp->mr_fsize), str);
     83 		dbg_print(lml, MSG_INTL(MSG_FIL_MMAPOBJ_2),
     84 		    EC_OFF(mpp->mr_offset), EC_OFF(mpp->mr_msize));
     85 	}
     86 	Dbg_util_nl(lml, DBG_NL_STD);
     87 }
     88 
     89 void
     90 Dbg_file_aout(Lm_list *lml, const char *name, Addr addr, size_t size,
     91     const char *lmid, Aliste lmco)
     92 {
     93 	if (DBG_NOTCLASS(DBG_C_FILES))
     94 		return;
     95 
     96 	dbg_print(lml, MSG_INTL(MSG_FIL_AOUT), name);
     97 	dbg_print(lml, MSG_INTL(MSG_FIL_DATA_AS), EC_ADDR(addr), EC_OFF(size));
     98 	dbg_print(lml, MSG_INTL(MSG_FIL_DATA_LL), lmid, EC_XWORD(lmco));
     99 }
    100 
    101 void
    102 Dbg_file_elf(Lm_list *lml, const char *name, Addr addr, size_t size,
    103     const char *lmid, Aliste lmco)
    104 {
    105 	const char	*str;
    106 
    107 	if (DBG_NOTCLASS(DBG_C_FILES))
    108 		return;
    109 
    110 	if (addr == 0)
    111 		str = MSG_INTL(MSG_STR_TEMPORARY);
    112 	else
    113 		str = MSG_ORIG(MSG_STR_EMPTY);
    114 
    115 	dbg_print(lml, MSG_INTL(MSG_FIL_ELF), name, str);
    116 	dbg_print(lml, MSG_INTL(MSG_FIL_DATA_AS), EC_ADDR(addr), EC_OFF(size));
    117 	dbg_print(lml, MSG_INTL(MSG_FIL_DATA_LL), lmid, EC_XWORD(lmco));
    118 }
    119 
    120 void
    121 Dbg_file_ldso(Rt_map *lmp, char **envp, auxv_t *auxv, const char *lmid,
    122     Aliste lmco)
    123 {
    124 	Lm_list	*lml = LIST(lmp);
    125 
    126 	if (DBG_NOTCLASS(DBG_C_FILES))
    127 		return;
    128 
    129 	Dbg_util_nl(lml, DBG_NL_STD);
    130 	dbg_print(lml, MSG_INTL(MSG_FIL_LDSO), PATHNAME(lmp));
    131 	dbg_print(lml, MSG_INTL(MSG_FIL_DATA_AS), EC_ADDR(ADDR(lmp)),
    132 	    EC_OFF(MSIZE(lmp)));
    133 	dbg_print(lml, MSG_INTL(MSG_FIL_DATA_EA), EC_NATPTR(envp),
    134 	    EC_NATPTR(auxv));
    135 	dbg_print(lml, MSG_INTL(MSG_FIL_DATA_LL), lmid, EC_XWORD(lmco));
    136 	Dbg_util_nl(lml, DBG_NL_STD);
    137 }
    138 
    139 
    140 void
    141 Dbg_file_prot(Rt_map *lmp, int prot)
    142 {
    143 	Lm_list	*lml = LIST(lmp);
    144 
    145 	if (DBG_NOTCLASS(DBG_C_FILES))
    146 		return;
    147 
    148 	Dbg_util_nl(lml, DBG_NL_STD);
    149 	dbg_print(lml, MSG_INTL(MSG_FIL_PROT), NAME(lmp), (prot ? '+' : '-'));
    150 }
    151 
    152 void
    153 Dbg_file_delete(Rt_map *lmp)
    154 {
    155 	Lm_list	*lml = LIST(lmp);
    156 
    157 	if (DBG_NOTCLASS(DBG_C_FILES))
    158 		return;
    159 
    160 	Dbg_util_nl(lml, DBG_NL_STD);
    161 	dbg_print(lml, MSG_INTL(MSG_FIL_DELETE), NAME(lmp));
    162 }
    163 
    164 static int	hdl_title = 0;
    165 static Msg	hdl_str = 0;
    166 
    167 void
    168 Dbg_file_hdl_title(int type)
    169 {
    170 	static const Msg titles[] = {
    171 		MSG_FIL_HDL_CREATE,	/* MSG_INTL(MSG_FIL_HDL_CREATE) */
    172 		MSG_FIL_HDL_ADD,	/* MSG_INTL(MSG_FIL_HDL_ADD) */
    173 		MSG_FIL_HDL_DELETE,	/* MSG_INTL(MSG_FIL_HDL_DELETE) */
    174 		MSG_FIL_HDL_ORPHAN,	/* MSG_INTL(MSG_FIL_HDL_ORPHAN) */
    175 		MSG_FIL_HDL_REINST,	/* MSG_INTL(MSG_FIL_HDL_REINST) */
    176 	};
    177 
    178 	if (DBG_NOTCLASS(DBG_C_FILES))
    179 		return;
    180 	if (DBG_NOTDETAIL())
    181 		return;
    182 
    183 	/*
    184 	 * Establish a binding title for later use in Dbg_file_hdl_action.
    185 	 */
    186 	if (type <= DBG_HDL_REINST) {
    187 		hdl_str = titles[type];
    188 		hdl_title = 1;
    189 	} else {
    190 		hdl_str = 0;
    191 		hdl_title = 0;
    192 	}
    193 }
    194 
    195 void
    196 Dbg_file_hdl_collect(Grp_hdl *ghp, const char *name)
    197 {
    198 	Conv_grphdl_flags_buf_t	grphdl_flags_buf;
    199 	Lm_list		*lml = ghp->gh_ownlml;
    200 	const char	*str;
    201 
    202 	if (DBG_NOTCLASS(DBG_C_FILES))
    203 		return;
    204 	if (DBG_NOTDETAIL())
    205 		return;
    206 
    207 	if (ghp->gh_ownlmp)
    208 		str = NAME(ghp->gh_ownlmp);
    209 	else
    210 		str = MSG_INTL(MSG_STR_ORPHAN);
    211 
    212 	if (hdl_title) {
    213 		hdl_title = 0;
    214 		Dbg_util_nl(lml, DBG_NL_STD);
    215 	}
    216 	if (name)
    217 		dbg_print(lml, MSG_INTL(MSG_FIL_HDL_RETAIN), str, name);
    218 	else
    219 		dbg_print(lml, MSG_INTL(MSG_FIL_HDL_COLLECT), str,
    220 		    conv_grphdl_flags(ghp->gh_flags, &grphdl_flags_buf));
    221 }
    222 
    223 void
    224 Dbg_file_hdl_action(Grp_hdl *ghp, Rt_map *lmp, int type, uint_t flags)
    225 {
    226 	Conv_grpdesc_flags_buf_t grpdesc_flags_buf;
    227 	const char	*mode, *group;
    228 	Lm_list		*lml = LIST(lmp);
    229 	Msg		str;
    230 
    231 	static const Msg fmt[] = {
    232 		MSG_FIL_DEP_ADD,	/* MSG_INTL(MSG_FIL_DEP_ADD) */
    233 		MSG_FIL_DEP_UPDATE,	/* MSG_INTL(MSG_FIL_DEP_UPDATE) */
    234 		MSG_FIL_DEP_DELETE,	/* MSG_INTL(MSG_FIL_DEP_DELETE) */
    235 		MSG_FIL_DEP_REMOVE,	/* MSG_INTL(MSG_FIL_DEP_REMOVE) */
    236 		MSG_FIL_DEP_REMAIN,	/* MSG_INTL(MSG_FIL_DEP_REMAIN) */
    237 		MSG_FIL_DEP_ORPHAN,	/* MSG_INTL(MSG_FIL_DEP_ORPHAN) */
    238 		MSG_FIL_DEP_REINST,	/* MSG_INTL(MSG_FIL_DEP_REINST) */
    239 	};
    240 	if (DBG_NOTCLASS(DBG_C_FILES))
    241 		return;
    242 	if (DBG_NOTDETAIL())
    243 		return;
    244 
    245 	if (hdl_title) {
    246 		Dbg_util_nl(lml, DBG_NL_STD);
    247 		if (hdl_str) {
    248 			Conv_grphdl_flags_buf_t grphdl_flags_buf;
    249 			const char	*name;
    250 
    251 			/*
    252 			 * Protect ourselves in case this handle has no
    253 			 * originating owner.
    254 			 */
    255 			if (ghp->gh_ownlmp)
    256 				name = NAME(ghp->gh_ownlmp);
    257 			else
    258 				name = MSG_INTL(MSG_STR_UNKNOWN);
    259 
    260 			dbg_print(lml, MSG_INTL(hdl_str), name,
    261 			    conv_grphdl_flags(ghp->gh_flags, &grphdl_flags_buf),
    262 			    EC_NATPTR(ghp));
    263 		}
    264 		hdl_title = 0;
    265 	}
    266 
    267 	/*
    268 	 * Establish a binding descriptor format string.
    269 	 */
    270 	if (type > DBG_DEP_REINST)
    271 		return;
    272 
    273 	str = fmt[type];
    274 
    275 	if (((type == DBG_DEP_ADD) || (type == DBG_DEP_UPDATE)) && flags)
    276 		group = conv_grpdesc_flags(flags, &grpdesc_flags_buf);
    277 	else
    278 		group = MSG_ORIG(MSG_STR_EMPTY);
    279 
    280 	if ((MODE(lmp) & (RTLD_GLOBAL | RTLD_NODELETE)) ==
    281 	    (RTLD_GLOBAL | RTLD_NODELETE))
    282 		mode = MSG_ORIG(MSG_MODE_GLOBNODEL);
    283 	else if (MODE(lmp) & RTLD_GLOBAL)
    284 		mode = MSG_ORIG(MSG_MODE_GLOB);
    285 	else if (MODE(lmp) & RTLD_NODELETE)
    286 		mode = MSG_ORIG(MSG_MODE_NODEL);
    287 	else
    288 		mode = MSG_ORIG(MSG_STR_EMPTY);
    289 
    290 	dbg_print(lml, MSG_INTL(str), NAME(lmp), mode, group);
    291 }
    292 
    293 void
    294 Dbg_file_bind_entry(Lm_list *lml, Bnd_desc *bdp)
    295 {
    296 	Conv_bnd_type_buf_t bnd_type_buf;
    297 
    298 	if (DBG_NOTCLASS(DBG_C_FILES))
    299 		return;
    300 	if (DBG_NOTDETAIL())
    301 		return;
    302 
    303 	/*
    304 	 * Print the dependency together with the modes of the binding.
    305 	 */
    306 	Dbg_util_nl(lml, DBG_NL_STD);
    307 	dbg_print(lml, MSG_INTL(MSG_FIL_BND_ADD), NAME(bdp->b_caller));
    308 	dbg_print(lml, MSG_INTL(MSG_FIL_BND_FILE), NAME(bdp->b_depend),
    309 	    conv_bnd_type(bdp->b_flags, &bnd_type_buf));
    310 }
    311 
    312 void
    313 Dbg_file_bindings(Rt_map *lmp, int flag)
    314 {
    315 	Conv_bnd_obj_buf_t	bnd_obj_buf;
    316 	Conv_bnd_type_buf_t	bnd_type_buf;
    317 	const char	*str;
    318 	Rt_map		*tlmp;
    319 	Lm_list		*lml = LIST(lmp);
    320 	int		next = 0;
    321 
    322 	if (DBG_NOTCLASS(DBG_C_INIT))
    323 		return;
    324 	if (DBG_NOTDETAIL())
    325 		return;
    326 
    327 	if (flag & RT_SORT_REV)
    328 		str = MSG_ORIG(MSG_SCN_INIT);
    329 	else
    330 		str = MSG_ORIG(MSG_SCN_FINI);
    331 
    332 	Dbg_util_nl(lml, DBG_NL_STD);
    333 	dbg_print(lml, MSG_INTL(MSG_FIL_DEP_TITLE), str,
    334 	    conv_bnd_obj(lml->lm_flags, &bnd_obj_buf));
    335 
    336 	/* LINTED */
    337 	for (tlmp = lmp; tlmp; tlmp = (Rt_map *)NEXT(tlmp)) {
    338 		Bnd_desc	*bdp;
    339 		Aliste		idx;
    340 
    341 		/*
    342 		 * For .init processing, only collect objects that have been
    343 		 * relocated and haven't already been collected.
    344 		 * For .fini processing, only collect objects that have had
    345 		 * their .init collected, and haven't already been .fini
    346 		 * collected.
    347 		 */
    348 		if (flag & RT_SORT_REV) {
    349 			if ((FLAGS(tlmp) & (FLG_RT_RELOCED |
    350 			    FLG_RT_INITCLCT)) != FLG_RT_RELOCED)
    351 				continue;
    352 
    353 		} else {
    354 			if ((flag & RT_SORT_DELETE) &&
    355 			    ((FLAGS(tlmp) & FLG_RT_DELETE) == 0))
    356 				continue;
    357 			if (((FLAGS(tlmp) &
    358 			    (FLG_RT_INITCLCT | FLG_RT_FINICLCT)) ==
    359 			    FLG_RT_INITCLCT) == 0)
    360 				continue;
    361 		}
    362 
    363 		if (next++)
    364 			Dbg_util_nl(lml, DBG_NL_STD);
    365 
    366 		if (DEPENDS(tlmp) == NULL)
    367 			dbg_print(lml, MSG_INTL(MSG_FIL_DEP_NONE), NAME(tlmp));
    368 		else {
    369 			dbg_print(lml, MSG_INTL(MSG_FIL_DEP_ENT), NAME(tlmp));
    370 
    371 			for (APLIST_TRAVERSE(DEPENDS(tlmp), idx, bdp)) {
    372 				dbg_print(lml, MSG_INTL(MSG_FIL_BND_FILE),
    373 				    NAME(bdp->b_depend),
    374 				    conv_bnd_type(bdp->b_flags,
    375 				    &bnd_type_buf));
    376 			}
    377 		}
    378 	}
    379 	Dbg_util_nl(lml, DBG_NL_STD);
    380 }
    381 
    382 void
    383 Dbg_file_dlopen(Rt_map *clmp, const char *name, int *in_nfavl, int mode)
    384 {
    385 	Conv_dl_mode_buf_t	dl_mode_buf;
    386 	Lm_list			*lml = LIST(clmp);
    387 	const char		*retry;
    388 
    389 	if (DBG_NOTCLASS(DBG_C_FILES))
    390 		return;
    391 
    392 	/*
    393 	 * The core functionality of dlopen() can be called twice.  The first
    394 	 * attempt can be affected by path names that exist in the "not-found"
    395 	 * AVL tree.  Should a "not-found" path name be found, a second attempt
    396 	 * is made to locate the required file (in_nfavl is NULL).  This fall-
    397 	 * back provides for file system changes while a process executes.
    398 	 */
    399 	if (in_nfavl)
    400 		retry = MSG_ORIG(MSG_STR_EMPTY);
    401 	else
    402 		retry = MSG_INTL(MSG_STR_RETRY);
    403 
    404 	Dbg_util_nl(lml, DBG_NL_STD);
    405 	dbg_print(lml, MSG_INTL(MSG_FIL_DLOPEN), name, NAME(clmp), retry,
    406 	    conv_dl_mode(mode, 0, &dl_mode_buf));
    407 }
    408 
    409 void
    410 Dbg_file_dlclose(Lm_list *lml, const char *name, int flag)
    411 {
    412 	const char	*str;
    413 
    414 	if (DBG_NOTCLASS(DBG_C_FILES))
    415 		return;
    416 
    417 	if (flag == DBG_DLCLOSE_IGNORE)
    418 		str = MSG_INTL(MSG_STR_IGNORE);
    419 	else
    420 		str = MSG_ORIG(MSG_STR_EMPTY);
    421 
    422 	Dbg_util_nl(lml, DBG_NL_STD);
    423 	dbg_print(lml, MSG_INTL(MSG_FIL_DLCLOSE), name, str);
    424 }
    425 
    426 void
    427 Dbg_file_dldump(Rt_map *lmp, const char *path, int flags)
    428 {
    429 	Conv_dl_flag_buf_t	dl_flag_buf;
    430 	Lm_list			*lml = LIST(lmp);
    431 
    432 	if (DBG_NOTCLASS(DBG_C_FILES))
    433 		return;
    434 
    435 	Dbg_util_nl(lml, DBG_NL_STD);
    436 	dbg_print(lml, MSG_INTL(MSG_FIL_DLDUMP), NAME(lmp), path,
    437 	    conv_dl_flag(flags, 0, &dl_flag_buf));
    438 }
    439 
    440 void
    441 Dbg_file_lazyload(Rt_map *clmp, const char *fname, const char *sname)
    442 {
    443 	Lm_list	*lml = LIST(clmp);
    444 
    445 	if (DBG_NOTCLASS(DBG_C_FILES))
    446 		return;
    447 
    448 	Dbg_util_nl(lml, DBG_NL_STD);
    449 	dbg_print(lml, MSG_INTL(MSG_FIL_LAZYLOAD), fname, NAME(clmp),
    450 	    Dbg_demangle_name(sname));
    451 }
    452 
    453 void
    454 Dbg_file_preload(Lm_list *lml, const char *name)
    455 {
    456 	if (DBG_NOTCLASS(DBG_C_FILES))
    457 		return;
    458 
    459 	Dbg_util_nl(lml, DBG_NL_STD);
    460 	dbg_print(lml, MSG_INTL(MSG_FIL_PRELOAD), name);
    461 }
    462 
    463 void
    464 Dbg_file_needed(Rt_map *lmp, const char *name)
    465 {
    466 	Lm_list	*lml = LIST(lmp);
    467 
    468 	if (DBG_NOTCLASS(DBG_C_FILES))
    469 		return;
    470 
    471 	Dbg_util_nl(lml, DBG_NL_STD);
    472 	dbg_print(lml, MSG_INTL(MSG_FIL_NEEDED), name, NAME(lmp));
    473 }
    474 
    475 void
    476 Dbg_file_filter(Lm_list *lml, const char *filter, const char *filtee,
    477     int config)
    478 {
    479 	if (DBG_NOTCLASS(DBG_C_FILES))
    480 		return;
    481 
    482 	Dbg_util_nl(lml, DBG_NL_STD);
    483 	if (config)
    484 		dbg_print(lml, MSG_INTL(MSG_FIL_FILTER_1), filter, filtee);
    485 	else
    486 		dbg_print(lml, MSG_INTL(MSG_FIL_FILTER_2), filter, filtee);
    487 }
    488 
    489 void
    490 Dbg_file_filtee(Lm_list *lml, const char *filter, const char *filtee, int audit)
    491 {
    492 	if (audit) {
    493 		if (DBG_NOTCLASS(DBG_C_AUDITING | DBG_C_FILES))
    494 			return;
    495 
    496 		Dbg_util_nl(lml, DBG_NL_STD);
    497 		dbg_print(lml, MSG_INTL(MSG_FIL_FILTEE_3), filtee);
    498 	} else {
    499 		if (DBG_NOTCLASS(DBG_C_FILES))
    500 			return;
    501 
    502 		Dbg_util_nl(lml, DBG_NL_STD);
    503 		if (filter)
    504 			dbg_print(lml, MSG_INTL(MSG_FIL_FILTEE_1), filtee,
    505 			    filter);
    506 		else
    507 			dbg_print(lml, MSG_INTL(MSG_FIL_FILTEE_2), filtee);
    508 	}
    509 }
    510 
    511 void
    512 Dbg_file_fixname(Lm_list *lml, const char *oname, const char *nname)
    513 {
    514 	if (DBG_NOTCLASS(DBG_C_FILES))
    515 		return;
    516 
    517 	Dbg_util_nl(lml, DBG_NL_STD);
    518 	dbg_print(lml, MSG_INTL(MSG_FIL_FIXNAME), oname, nname);
    519 }
    520 
    521 void
    522 Dbg_file_output(Ofl_desc *ofl)
    523 {
    524 	const char	*prefix = MSG_ORIG(MSG_PTH_OBJECT);
    525 	char		*oname, *nname, *ofile;
    526 	int		fd;
    527 
    528 	if (DBG_NOTCLASS(DBG_C_FILES))
    529 		return;
    530 	if (DBG_NOTDETAIL())
    531 		return;
    532 
    533 	/*
    534 	 * Obtain the present input object filename for concatenation to the
    535 	 * prefix name.
    536 	 */
    537 	oname = (char *)ofl->ofl_name;
    538 	if ((ofile = strrchr(oname, '/')) == NULL)
    539 		ofile = oname;
    540 	else
    541 		ofile++;
    542 
    543 	/*
    544 	 * Concatenate the prefix with the object filename, open the file and
    545 	 * write out the present Elf memory image.  As this is debugging we
    546 	 * ignore all errors.
    547 	 */
    548 	if ((nname = malloc(strlen(prefix) + strlen(ofile) + 1)) != 0) {
    549 		(void) strcpy(nname, prefix);
    550 		(void) strcat(nname, ofile);
    551 		if ((fd = open(nname, O_RDWR | O_CREAT | O_TRUNC,
    552 		    0666)) != -1) {
    553 			(void) write(fd, ofl->ofl_nehdr, ofl->ofl_size);
    554 			(void) close(fd);
    555 		}
    556 		free(nname);
    557 	}
    558 }
    559 
    560 void
    561 Dbg_file_config_dis(Lm_list *lml, const char *config, int features)
    562 {
    563 	Conv_config_feat_buf_t	config_feat_buf;
    564 	const char		*str;
    565 
    566 	switch (features & ~CONF_FEATMSK) {
    567 	case DBG_CONF_IGNORE:
    568 		str = MSG_INTL(MSG_FIL_CONFIG_ERR_1);
    569 		break;
    570 	case DBG_CONF_VERSION:
    571 		str = MSG_INTL(MSG_FIL_CONFIG_ERR_2);
    572 		break;
    573 	case DBG_CONF_PRCFAIL:
    574 		str = MSG_INTL(MSG_FIL_CONFIG_ERR_3);
    575 		break;
    576 	case DBG_CONF_CORRUPT:
    577 		str = MSG_INTL(MSG_FIL_CONFIG_ERR_4);
    578 		break;
    579 	case DBG_CONF_ABIMISMATCH:
    580 		str = MSG_INTL(MSG_FIL_CONFIG_ERR_5);
    581 		break;
    582 	default:
    583 		str = conv_config_feat(features, &config_feat_buf);
    584 		break;
    585 	}
    586 
    587 	Dbg_util_nl(lml, DBG_NL_FRC);
    588 	dbg_print(lml, MSG_INTL(MSG_FIL_CONFIG_ERR), config, str);
    589 	Dbg_util_nl(lml, DBG_NL_FRC);
    590 }
    591 
    592 void
    593 Dbg_file_config_obj(Lm_list *lml, const char *dir, const char *file,
    594     const char *config)
    595 {
    596 	char	*name, _name[PATH_MAX];
    597 
    598 	if (DBG_NOTCLASS(DBG_C_FILES))
    599 		return;
    600 
    601 	if (file) {
    602 		(void) snprintf(_name, PATH_MAX, MSG_ORIG(MSG_FMT_PATH),
    603 		    dir, file);
    604 		name = _name;
    605 	} else
    606 		name = (char *)dir;
    607 
    608 	dbg_print(lml, MSG_INTL(MSG_FIL_CONFIG), name, config);
    609 }
    610 
    611 void
    612 Dbg_file_del_rescan(Lm_list *lml)
    613 {
    614 	if (DBG_NOTCLASS(DBG_C_FILES))
    615 		return;
    616 
    617 	Dbg_util_nl(lml, DBG_NL_STD);
    618 	dbg_print(lml, MSG_INTL(MSG_FIL_DEL_RESCAN));
    619 }
    620 
    621 void
    622 Dbg_file_mode_promote(Rt_map *lmp, int mode)
    623 {
    624 	Conv_dl_mode_buf_t	dl_mode_buf;
    625 	Lm_list			*lml = LIST(lmp);
    626 
    627 	if (DBG_NOTCLASS(DBG_C_FILES))
    628 		return;
    629 
    630 	Dbg_util_nl(lml, DBG_NL_STD);
    631 	dbg_print(lml, MSG_INTL(MSG_FIL_PROMOTE), NAME(lmp),
    632 	    conv_dl_mode(mode, 0, &dl_mode_buf));
    633 	Dbg_util_nl(lml, DBG_NL_STD);
    634 }
    635 
    636 void
    637 Dbg_file_cntl(Lm_list *lml, Aliste flmco, Aliste tlmco)
    638 {
    639 	Lm_cntl	*lmc;
    640 	Aliste	off;
    641 
    642 	if (DBG_NOTCLASS(DBG_C_FILES))
    643 		return;
    644 	if (DBG_NOTDETAIL())
    645 		return;
    646 
    647 	Dbg_util_nl(lml, DBG_NL_STD);
    648 	dbg_print(lml, MSG_INTL(MSG_CNTL_TITLE), EC_XWORD(flmco),
    649 	    EC_XWORD(tlmco));
    650 
    651 	for (ALIST_TRAVERSE_BY_OFFSET(lml->lm_lists, off, lmc)) {
    652 		Rt_map	*lmp;
    653 
    654 		/* LINTED */
    655 		for (lmp = lmc->lc_head; lmp; lmp = (Rt_map *)NEXT(lmp))
    656 			dbg_print(lml, MSG_ORIG(MSG_CNTL_ENTRY), EC_XWORD(off),
    657 			    NAME(lmp));
    658 	}
    659 	Dbg_util_nl(lml, DBG_NL_STD);
    660 }
    661 
    662 /*
    663  * Report archive rescan operation.
    664  *	argv_start_ndx, argv_end_ndx - Index range of command line arguments
    665  *		from which archives are to be reprocessed.
    666  */
    667 void
    668 Dbg_file_ar_rescan(Lm_list *lml, int argv_start_ndx, int argv_end_ndx)
    669 {
    670 	if (DBG_NOTCLASS(DBG_C_FILES))
    671 		return;
    672 
    673 	Dbg_util_nl(lml, DBG_NL_STD);
    674 	dbg_print(lml, MSG_INTL(MSG_FIL_AR_RESCAN),
    675 	    argv_start_ndx, argv_end_ndx);
    676 	Dbg_util_nl(lml, DBG_NL_STD);
    677 }
    678 
    679 void
    680 Dbg_file_ar(Lm_list *lml, const char *name, int again)
    681 {
    682 	const char	*str;
    683 
    684 	if (DBG_NOTCLASS(DBG_C_FILES))
    685 		return;
    686 
    687 	if (again)
    688 		str = MSG_INTL(MSG_STR_AGAIN);
    689 	else
    690 		str = MSG_ORIG(MSG_STR_EMPTY);
    691 
    692 	Dbg_util_nl(lml, DBG_NL_STD);
    693 	dbg_print(lml, MSG_INTL(MSG_FIL_ARCHIVE), name, str);
    694 }
    695 
    696 void
    697 Dbg_file_generic(Lm_list *lml, Ifl_desc *ifl)
    698 {
    699 	Conv_inv_buf_t inv_buf;
    700 
    701 	if (DBG_NOTCLASS(DBG_C_FILES))
    702 		return;
    703 
    704 	Dbg_util_nl(lml, DBG_NL_STD);
    705 	dbg_print(lml, MSG_INTL(MSG_FIL_BASIC), ifl->ifl_name,
    706 	    conv_ehdr_type(ifl->ifl_ehdr->e_ident[EI_OSABI],
    707 	    ifl->ifl_ehdr->e_type, 0, &inv_buf));
    708 }
    709 
    710 static const Msg
    711 reject[] = {
    712 	MSG_STR_EMPTY,
    713 	MSG_REJ_MACH,		/* MSG_INTL(MSG_REJ_MACH) */
    714 	MSG_REJ_CLASS,		/* MSG_INTL(MSG_REJ_CLASS) */
    715 	MSG_REJ_DATA,		/* MSG_INTL(MSG_REJ_DATA) */
    716 	MSG_REJ_TYPE,		/* MSG_INTL(MSG_REJ_TYPE) */
    717 	MSG_REJ_BADFLAG,	/* MSG_INTL(MSG_REJ_BADFLAG) */
    718 	MSG_REJ_MISFLAG,	/* MSG_INTL(MSG_REJ_MISFLAG) */
    719 	MSG_REJ_VERSION,	/* MSG_INTL(MSG_REJ_VERSION) */
    720 	MSG_REJ_HAL,		/* MSG_INTL(MSG_REJ_HAL) */
    721 	MSG_REJ_US3,		/* MSG_INTL(MSG_REJ_US3) */
    722 	MSG_REJ_STR,		/* MSG_INTL(MSG_REJ_STR) */
    723 	MSG_REJ_UNKFILE,	/* MSG_INTL(MSG_REJ_UNKFILE) */
    724 	MSG_REJ_HWCAP_1,	/* MSG_INTL(MSG_REJ_HWCAP_1) */
    725 };
    726 
    727 void
    728 Dbg_file_rejected(Lm_list *lml, Rej_desc *rej, Half mach)
    729 {
    730 	Conv_reject_desc_buf_t rej_buf;
    731 
    732 	if (DBG_NOTCLASS(DBG_C_FILES))
    733 		return;
    734 
    735 	Dbg_util_nl(lml, DBG_NL_STD);
    736 	dbg_print(lml, MSG_INTL(reject[rej->rej_type]), rej->rej_name ?
    737 	    rej->rej_name : MSG_INTL(MSG_STR_UNKNOWN),
    738 	    conv_reject_desc(rej, &rej_buf, mach));
    739 	Dbg_util_nl(lml, DBG_NL_STD);
    740 }
    741 
    742 void
    743 Dbg_file_reuse(Lm_list *lml, const char *nname, const char *oname)
    744 {
    745 	if (DBG_NOTCLASS(DBG_C_FILES))
    746 		return;
    747 
    748 	dbg_print(lml, MSG_INTL(MSG_FIL_REUSE), nname, oname);
    749 }
    750 
    751 void
    752 Dbg_file_skip(Lm_list *lml, const char *oname, const char *nname)
    753 {
    754 	if (DBG_NOTCLASS(DBG_C_FILES))
    755 		return;
    756 
    757 	if (oname && strcmp(nname, oname))
    758 		dbg_print(lml, MSG_INTL(MSG_FIL_SKIP_1), nname, oname);
    759 	else
    760 		dbg_print(lml, MSG_INTL(MSG_FIL_SKIP_2), nname);
    761 }
    762 
    763 void
    764 Dbg_file_modified(Lm_list *lml, const char *obj, const char *oname,
    765     const char *nname, int ofd, int nfd, Elf *oelf, Elf *nelf)
    766 {
    767 	const char	*str;
    768 
    769 	if (DBG_NOTCLASS(DBG_C_FILES | DBG_C_SUPPORT))
    770 		return;
    771 	if (DBG_NOTDETAIL())
    772 		return;
    773 
    774 	Dbg_util_nl(lml, DBG_NL_STD);
    775 	dbg_print(lml, MSG_INTL(MSG_FIL_MODIFIED), oname, obj);
    776 
    777 	if (nname != oname)
    778 		dbg_print(lml, MSG_INTL(MSG_FIL_NAMECHANGE), nname);
    779 	if (nfd != ofd) {
    780 		if (nfd == -1)
    781 			str = MSG_INTL(MSG_FIL_IGNORE);
    782 		else
    783 			str = MSG_ORIG(MSG_STR_EMPTY);
    784 		dbg_print(lml, MSG_INTL(MSG_FIL_FDCHANGE), ofd, nfd, str);
    785 	}
    786 	if (nelf != oelf) {
    787 		if (nelf == 0)
    788 			str = MSG_INTL(MSG_FIL_IGNORE);
    789 		else
    790 			str = MSG_ORIG(MSG_STR_EMPTY);
    791 		dbg_print(lml, MSG_INTL(MSG_FIL_ELFCHANGE), EC_NATPTR(oelf),
    792 		    EC_NATPTR(nelf), str);
    793 	}
    794 	Dbg_util_nl(lml, DBG_NL_STD);
    795 }
    796 
    797 void
    798 Dbg_file_cleanup(Lm_list *lml, const char *name, Aliste lmco)
    799 {
    800 	if (DBG_NOTCLASS(DBG_C_FILES))
    801 		return;
    802 
    803 	Dbg_util_nl(lml, DBG_NL_STD);
    804 	dbg_print(lml, MSG_INTL(MSG_FIL_CLEANUP), name, EC_XWORD(lmco));
    805 }
    806