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