xref: /illumos-gate/usr/src/cmd/sgs/liblddbg/common/files.c (revision fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8)
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 2007 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 	if (DBG_NOTCLASS(DBG_C_FILES))
141 		return;
142 	if (DBG_NOTDETAIL())
143 		return;
144 
145 	hdl_title = 1;
146 
147 	/*
148 	 * Establish a binding title for later use in Dbg_file_bind_entry.
149 	 * These are to be used with the MSG_INTL() macro.
150 	 *
151 	 * Note: The following are to convince chkmsg.sh that these
152 	 * messages are actually used:
153 	 *
154 	 *	MSG_INTL(MSG_FIL_HDL_CREATE)
155 	 *	MSG_INTL(MSG_FIL_HDL_ADD)
156 	 *	MSG_INTL(MSG_FIL_HDL_DELETE)
157 	 *	MSG_INTL(MSG_FIL_HDL_ORPHAN)
158 	 *	MSG_INTL(MSG_FIL_HDL_REINST)
159 	 */
160 	switch (type) {
161 	case DBG_DEP_CREATE:
162 		hdl_str = MSG_FIL_HDL_CREATE;
163 		break;
164 	case DBG_DEP_ADD:
165 		hdl_str = MSG_FIL_HDL_ADD;
166 		break;
167 	case DBG_DEP_DELETE:
168 		hdl_str = MSG_FIL_HDL_DELETE;
169 		break;
170 	case DBG_DEP_ORPHAN:
171 		hdl_str = MSG_FIL_HDL_ORPHAN;
172 		break;
173 	case DBG_DEP_REINST:
174 		hdl_str = MSG_FIL_HDL_REINST;
175 		break;
176 	default:
177 		hdl_str = 0;
178 		break;
179 	}
180 }
181 
182 void
183 Dbg_file_hdl_collect(Grp_hdl *ghp, const char *name)
184 {
185 	Conv_grphdl_flags_buf_t	grphdl_flags_buf;
186 	Lm_list		*lml = ghp->gh_ownlml;
187 	const char	*str;
188 
189 	if (DBG_NOTCLASS(DBG_C_FILES))
190 		return;
191 	if (DBG_NOTDETAIL())
192 		return;
193 
194 	if (ghp->gh_ownlmp)
195 		str = NAME(ghp->gh_ownlmp);
196 	else
197 		str = MSG_INTL(MSG_STR_ORPHAN);
198 
199 	if (hdl_title) {
200 		hdl_title = 0;
201 		Dbg_util_nl(lml, DBG_NL_STD);
202 	}
203 	if (name)
204 		dbg_print(lml, MSG_INTL(MSG_FIL_HDL_RETAIN), str, name);
205 	else
206 		dbg_print(lml, MSG_INTL(MSG_FIL_HDL_COLLECT), str,
207 		    conv_grphdl_flags(ghp->gh_flags, &grphdl_flags_buf));
208 }
209 
210 void
211 Dbg_file_hdl_action(Grp_hdl *ghp, Rt_map *lmp, int type, uint_t flags)
212 {
213 	Conv_grpdesc_flags_buf_t grpdesc_flags_buf;
214 	const char	*mode, *group;
215 	Lm_list		*lml = LIST(lmp);
216 	Msg		str;
217 
218 	if (DBG_NOTCLASS(DBG_C_FILES))
219 		return;
220 	if (DBG_NOTDETAIL())
221 		return;
222 
223 	if (hdl_title) {
224 		Dbg_util_nl(lml, DBG_NL_STD);
225 		if (hdl_str) {
226 			const char	*name;
227 
228 			/*
229 			 * Protect ourselves in case this handle has no
230 			 * originating owner.
231 			 */
232 			if (ghp->gh_ownlmp)
233 				name = NAME(ghp->gh_ownlmp);
234 			else
235 				name = MSG_INTL(MSG_STR_UNKNOWN);
236 
237 			dbg_print(lml, MSG_INTL(hdl_str), name);
238 		}
239 		hdl_title = 0;
240 	}
241 
242 	/*
243 	 * Note: The following are to convince chkmsg.sh that these
244 	 * messages are actually used:
245 	 *
246 	 *	MSG_INTL(MSG_FIL_DEP_ADD)
247 	 *	MSG_INTL(MSG_FIL_DEP_DELETE)
248 	 *	MSG_INTL(MSG_FIL_DEP_REMOVE)
249 	 *	MSG_INTL(MSG_FIL_DEP_REMAIN)
250 	 *	MSG_INTL(MSG_FIL_DEP_ORPHAN)
251 	 *	MSG_INTL(MSG_FIL_DEP_REINST)
252 	 */
253 	switch (type) {
254 	case DBG_DEP_ADD:
255 		str = MSG_FIL_DEP_ADD;
256 		break;
257 	case DBG_DEP_DELETE:
258 		str = MSG_FIL_DEP_DELETE;
259 		break;
260 	case DBG_DEP_REMOVE:
261 		str = MSG_FIL_DEP_REMOVE;
262 		break;
263 	case DBG_DEP_REMAIN:
264 		str = MSG_FIL_DEP_REMAIN;
265 		break;
266 	case DBG_DEP_ORPHAN:
267 		str = MSG_FIL_DEP_ORPHAN;
268 		break;
269 	case DBG_DEP_REINST:
270 		str = MSG_FIL_DEP_REINST;
271 		break;
272 	default:
273 		return;
274 	}
275 
276 	if ((type == DBG_DEP_ADD) && flags)
277 		group = conv_grpdesc_flags(flags, &grpdesc_flags_buf);
278 	else
279 		group = MSG_ORIG(MSG_STR_EMPTY);
280 
281 	if ((MODE(lmp) & (RTLD_GLOBAL | RTLD_NODELETE)) ==
282 	    (RTLD_GLOBAL | RTLD_NODELETE))
283 		mode = MSG_ORIG(MSG_MODE_GLOBNODEL);
284 	else if (MODE(lmp) & RTLD_GLOBAL)
285 		mode = MSG_ORIG(MSG_MODE_GLOB);
286 
287 	else if (MODE(lmp) & RTLD_NODELETE)
288 		mode = MSG_ORIG(MSG_MODE_NODEL);
289 	else
290 		mode = MSG_ORIG(MSG_STR_EMPTY);
291 
292 	dbg_print(lml, MSG_INTL(str), NAME(lmp), mode, group);
293 }
294 
295 void
296 Dbg_file_bind_entry(Lm_list *lml, Bnd_desc *bdp)
297 {
298 	Conv_bnd_type_buf_t bnd_type_buf;
299 
300 	if (DBG_NOTCLASS(DBG_C_FILES))
301 		return;
302 	if (DBG_NOTDETAIL())
303 		return;
304 
305 	/*
306 	 * Print the dependency together with the modes of the binding.
307 	 */
308 	Dbg_util_nl(lml, DBG_NL_STD);
309 	dbg_print(lml, MSG_INTL(MSG_FIL_BND_ADD), NAME(bdp->b_caller));
310 	dbg_print(lml, MSG_INTL(MSG_FIL_BND_FILE), NAME(bdp->b_depend),
311 	    conv_bnd_type(bdp->b_flags, &bnd_type_buf));
312 }
313 
314 void
315 Dbg_file_bindings(Rt_map *lmp, int flag)
316 {
317 	Conv_bnd_obj_buf_t	bnd_obj_buf;
318 	Conv_bnd_type_buf_t	bnd_type_buf;
319 	const char	*str;
320 	Rt_map		*tlmp;
321 	Lm_list		*lml = LIST(lmp);
322 	int		next = 0;
323 
324 	if (DBG_NOTCLASS(DBG_C_INIT))
325 		return;
326 	if (DBG_NOTDETAIL())
327 		return;
328 
329 	if (flag & RT_SORT_REV)
330 		str = MSG_ORIG(MSG_SCN_INIT);
331 	else
332 		str = MSG_ORIG(MSG_SCN_FINI);
333 
334 	Dbg_util_nl(lml, DBG_NL_STD);
335 	dbg_print(lml, MSG_INTL(MSG_FIL_DEP_TITLE), str,
336 	    conv_bnd_obj(lml->lm_flags, &bnd_obj_buf));
337 
338 	/* LINTED */
339 	for (tlmp = lmp; tlmp; tlmp = (Rt_map *)NEXT(tlmp)) {
340 		Bnd_desc	**bdpp;
341 		Aliste		off;
342 
343 		/*
344 		 * For .init processing, only collect objects that have been
345 		 * relocated and haven't already been collected.
346 		 * For .fini processing, only collect objects that have had
347 		 * their .init collected, and haven't already been .fini
348 		 * collected.
349 		 */
350 		if (flag & RT_SORT_REV) {
351 			if ((FLAGS(tlmp) & (FLG_RT_RELOCED |
352 			    FLG_RT_INITCLCT)) != FLG_RT_RELOCED)
353 				continue;
354 
355 		} else {
356 			if ((flag & RT_SORT_DELETE) &&
357 			    ((FLAGS(tlmp) & FLG_RT_DELETE) == 0))
358 				continue;
359 			if (((FLAGS(tlmp) &
360 			    (FLG_RT_INITCLCT | FLG_RT_FINICLCT)) ==
361 			    FLG_RT_INITCLCT) == 0)
362 				continue;
363 		}
364 
365 		if (next++)
366 			Dbg_util_nl(lml, DBG_NL_STD);
367 
368 		if (DEPENDS(tlmp) == 0)
369 			dbg_print(lml, MSG_INTL(MSG_FIL_DEP_NONE), NAME(tlmp));
370 		else {
371 			dbg_print(lml, MSG_INTL(MSG_FIL_DEP_ENT), NAME(tlmp));
372 
373 			for (ALIST_TRAVERSE(DEPENDS(tlmp), off, bdpp)) {
374 				dbg_print(lml, MSG_INTL(MSG_FIL_BND_FILE),
375 				    NAME((*bdpp)->b_depend),
376 				    conv_bnd_type((*bdpp)->b_flags,
377 				    &bnd_type_buf));
378 			}
379 		}
380 	}
381 	Dbg_util_nl(lml, DBG_NL_STD);
382 }
383 
384 void
385 Dbg_file_dlopen(Rt_map *clmp, const char *name, int mode)
386 {
387 	Conv_dl_mode_buf_t	dl_mode_buf;
388 	Lm_list			*lml = LIST(clmp);
389 
390 	if (DBG_NOTCLASS(DBG_C_FILES))
391 		return;
392 
393 	Dbg_util_nl(lml, DBG_NL_STD);
394 	dbg_print(lml, MSG_INTL(MSG_FIL_DLOPEN), name, NAME(clmp),
395 	    conv_dl_mode(mode, 1, &dl_mode_buf));
396 }
397 
398 void
399 Dbg_file_dlclose(Lm_list *lml, const char *name, int flag)
400 {
401 	const char	*str;
402 
403 	if (DBG_NOTCLASS(DBG_C_FILES))
404 		return;
405 
406 	if (flag == DBG_DLCLOSE_IGNORE)
407 		str = MSG_INTL(MSG_STR_IGNORE);
408 	else
409 		str = MSG_ORIG(MSG_STR_EMPTY);
410 
411 	Dbg_util_nl(lml, DBG_NL_STD);
412 	dbg_print(lml, MSG_INTL(MSG_FIL_DLCLOSE), name, str);
413 }
414 
415 void
416 Dbg_file_dldump(Rt_map *lmp, const char *path, int flags)
417 {
418 	Conv_dl_flag_buf_t	dl_flag_buf;
419 	Lm_list			*lml = LIST(lmp);
420 
421 	if (DBG_NOTCLASS(DBG_C_FILES))
422 		return;
423 
424 	Dbg_util_nl(lml, DBG_NL_STD);
425 	dbg_print(lml, MSG_INTL(MSG_FIL_DLDUMP), NAME(lmp), path,
426 	    conv_dl_flag(flags, 0, &dl_flag_buf));
427 }
428 
429 void
430 Dbg_file_lazyload(Rt_map *clmp, const char *fname, const char *sname)
431 {
432 	Lm_list	*lml = LIST(clmp);
433 
434 	if (DBG_NOTCLASS(DBG_C_FILES))
435 		return;
436 
437 	Dbg_util_nl(lml, DBG_NL_STD);
438 	dbg_print(lml, MSG_INTL(MSG_FIL_LAZYLOAD), fname, NAME(clmp),
439 	    Dbg_demangle_name(sname));
440 }
441 
442 void
443 Dbg_file_preload(Lm_list *lml, const char *name)
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_PRELOAD), name);
450 }
451 
452 void
453 Dbg_file_needed(Rt_map *lmp, const char *name)
454 {
455 	Lm_list	*lml = LIST(lmp);
456 
457 	if (DBG_NOTCLASS(DBG_C_FILES))
458 		return;
459 
460 	Dbg_util_nl(lml, DBG_NL_STD);
461 	dbg_print(lml, MSG_INTL(MSG_FIL_NEEDED), name, NAME(lmp));
462 }
463 
464 void
465 Dbg_file_filter(Lm_list *lml, const char *filter, const char *filtee,
466     int config)
467 {
468 	if (DBG_NOTCLASS(DBG_C_FILES))
469 		return;
470 
471 	Dbg_util_nl(lml, DBG_NL_STD);
472 	if (config)
473 		dbg_print(lml, MSG_INTL(MSG_FIL_FILTER_1), filter, filtee);
474 	else
475 		dbg_print(lml, MSG_INTL(MSG_FIL_FILTER_2), filter, filtee);
476 }
477 
478 void
479 Dbg_file_filtee(Lm_list *lml, const char *filter, const char *filtee, int audit)
480 {
481 	if (audit) {
482 		if (DBG_NOTCLASS(DBG_C_AUDITING | DBG_C_FILES))
483 			return;
484 
485 		Dbg_util_nl(lml, DBG_NL_STD);
486 		dbg_print(lml, MSG_INTL(MSG_FIL_FILTEE_3), filtee);
487 	} else {
488 		if (DBG_NOTCLASS(DBG_C_FILES))
489 			return;
490 
491 		Dbg_util_nl(lml, DBG_NL_STD);
492 		if (filter)
493 			dbg_print(lml, MSG_INTL(MSG_FIL_FILTEE_1), filtee,
494 			    filter);
495 		else
496 			dbg_print(lml, MSG_INTL(MSG_FIL_FILTEE_2), filtee);
497 	}
498 }
499 
500 void
501 Dbg_file_fixname(Lm_list *lml, const char *oname, const char *nname)
502 {
503 	if (DBG_NOTCLASS(DBG_C_FILES))
504 		return;
505 
506 	Dbg_util_nl(lml, DBG_NL_STD);
507 	dbg_print(lml, MSG_INTL(MSG_FIL_FIXNAME), oname, nname);
508 }
509 
510 void
511 Dbg_file_output(Ofl_desc *ofl)
512 {
513 	const char	*prefix = MSG_ORIG(MSG_PTH_OBJECT);
514 	char		*oname, *nname, *ofile;
515 	int		fd;
516 
517 	if (DBG_NOTCLASS(DBG_C_FILES))
518 		return;
519 	if (DBG_NOTDETAIL())
520 		return;
521 
522 	/*
523 	 * Obtain the present input object filename for concatenation to the
524 	 * prefix name.
525 	 */
526 	oname = (char *)ofl->ofl_name;
527 	if ((ofile = strrchr(oname, '/')) == NULL)
528 		ofile = oname;
529 	else
530 		ofile++;
531 
532 	/*
533 	 * Concatenate the prefix with the object filename, open the file and
534 	 * write out the present Elf memory image.  As this is debugging we
535 	 * ignore all errors.
536 	 */
537 	if ((nname = malloc(strlen(prefix) + strlen(ofile) + 1)) != 0) {
538 		(void) strcpy(nname, prefix);
539 		(void) strcat(nname, ofile);
540 		if ((fd = open(nname, O_RDWR | O_CREAT | O_TRUNC,
541 		    0666)) != -1) {
542 			(void) write(fd, ofl->ofl_nehdr, ofl->ofl_size);
543 			(void) close(fd);
544 		}
545 		free(nname);
546 	}
547 }
548 
549 void
550 Dbg_file_config_dis(Lm_list *lml, const char *config, int features)
551 {
552 	Conv_config_feat_buf_t	config_feat_buf;
553 	const char		*str;
554 
555 	switch (features & ~CONF_FEATMSK) {
556 	case DBG_CONF_IGNORE:
557 		str = MSG_INTL(MSG_FIL_CONFIG_ERR_1);
558 		break;
559 	case DBG_CONF_VERSION:
560 		str = MSG_INTL(MSG_FIL_CONFIG_ERR_2);
561 		break;
562 	case DBG_CONF_PRCFAIL:
563 		str = MSG_INTL(MSG_FIL_CONFIG_ERR_3);
564 		break;
565 	case DBG_CONF_CORRUPT:
566 		str = MSG_INTL(MSG_FIL_CONFIG_ERR_4);
567 		break;
568 	case DBG_CONF_ABIMISMATCH:
569 		str = MSG_INTL(MSG_FIL_CONFIG_ERR_5);
570 		break;
571 	default:
572 		str = conv_config_feat(features, &config_feat_buf);
573 		break;
574 	}
575 
576 	Dbg_util_nl(lml, DBG_NL_FRC);
577 	dbg_print(lml, MSG_INTL(MSG_FIL_CONFIG_ERR), config, str);
578 	Dbg_util_nl(lml, DBG_NL_FRC);
579 }
580 
581 void
582 Dbg_file_config_obj(Lm_list *lml, const char *dir, const char *file,
583     const char *config)
584 {
585 	char	*name, _name[PATH_MAX];
586 
587 	if (DBG_NOTCLASS(DBG_C_FILES))
588 		return;
589 
590 	if (file) {
591 		(void) snprintf(_name, PATH_MAX, MSG_ORIG(MSG_FMT_PATH),
592 		    dir, file);
593 		name = _name;
594 	} else
595 		name = (char *)dir;
596 
597 	dbg_print(lml, MSG_INTL(MSG_FIL_CONFIG), name, config);
598 }
599 
600 void
601 Dbg_file_del_rescan(Lm_list *lml)
602 {
603 	if (DBG_NOTCLASS(DBG_C_FILES))
604 		return;
605 
606 	Dbg_util_nl(lml, DBG_NL_STD);
607 	dbg_print(lml, MSG_INTL(MSG_FIL_DEL_RESCAN));
608 }
609 
610 void
611 Dbg_file_mode_promote(Rt_map *lmp, int mode)
612 {
613 	Conv_dl_mode_buf_t	dl_mode_buf;
614 	Lm_list			*lml = LIST(lmp);
615 
616 	if (DBG_NOTCLASS(DBG_C_FILES))
617 		return;
618 
619 	Dbg_util_nl(lml, DBG_NL_STD);
620 	dbg_print(lml, MSG_INTL(MSG_FIL_PROMOTE), NAME(lmp),
621 	    conv_dl_mode(mode, 0, &dl_mode_buf));
622 	Dbg_util_nl(lml, DBG_NL_STD);
623 }
624 
625 void
626 Dbg_file_cntl(Lm_list *lml, Aliste flmco, Aliste tlmco)
627 {
628 	Lm_cntl	*lmc;
629 	Aliste	off;
630 
631 	if (DBG_NOTCLASS(DBG_C_FILES))
632 		return;
633 	if (DBG_NOTDETAIL())
634 		return;
635 
636 	Dbg_util_nl(lml, DBG_NL_STD);
637 	dbg_print(lml, MSG_INTL(MSG_CNTL_TITLE), EC_XWORD(flmco),
638 	    EC_XWORD(tlmco));
639 
640 	for (ALIST_TRAVERSE(lml->lm_lists, off, lmc)) {
641 		Rt_map	*lmp;
642 
643 		/* LINTED */
644 		for (lmp = lmc->lc_head; lmp; lmp = (Rt_map *)NEXT(lmp))
645 			dbg_print(lml, MSG_ORIG(MSG_CNTL_ENTRY), EC_XWORD(off),
646 			    NAME(lmp));
647 	}
648 	Dbg_util_nl(lml, DBG_NL_STD);
649 }
650 
651 void
652 Dbg_file_ar_rescan(Lm_list *lml)
653 {
654 	if (DBG_NOTCLASS(DBG_C_FILES))
655 		return;
656 
657 	Dbg_util_nl(lml, DBG_NL_STD);
658 	dbg_print(lml, MSG_INTL(MSG_FIL_AR_RESCAN));
659 	Dbg_util_nl(lml, DBG_NL_STD);
660 }
661 
662 void
663 Dbg_file_ar(Lm_list *lml, const char *name, int again)
664 {
665 	const char	*str;
666 
667 	if (DBG_NOTCLASS(DBG_C_FILES))
668 		return;
669 
670 	if (again)
671 		str = MSG_INTL(MSG_STR_AGAIN);
672 	else
673 		str = MSG_ORIG(MSG_STR_EMPTY);
674 
675 	Dbg_util_nl(lml, DBG_NL_STD);
676 	dbg_print(lml, MSG_INTL(MSG_FIL_ARCHIVE), name, str);
677 }
678 
679 void
680 Dbg_file_generic(Lm_list *lml, Ifl_desc *ifl)
681 {
682 	Conv_inv_buf_t inv_buf;
683 
684 	if (DBG_NOTCLASS(DBG_C_FILES))
685 		return;
686 
687 	Dbg_util_nl(lml, DBG_NL_STD);
688 	dbg_print(lml, MSG_INTL(MSG_FIL_BASIC), ifl->ifl_name,
689 	    conv_ehdr_type(ifl->ifl_ehdr->e_type, 0, &inv_buf));
690 }
691 
692 static const Msg
693 reject[] = {
694 	MSG_STR_EMPTY,
695 	MSG_REJ_MACH,		/* MSG_INTL(MSG_REJ_MACH) */
696 	MSG_REJ_CLASS,		/* MSG_INTL(MSG_REJ_CLASS) */
697 	MSG_REJ_DATA,		/* MSG_INTL(MSG_REJ_DATA) */
698 	MSG_REJ_TYPE,		/* MSG_INTL(MSG_REJ_TYPE) */
699 	MSG_REJ_BADFLAG,	/* MSG_INTL(MSG_REJ_BADFLAG) */
700 	MSG_REJ_MISFLAG,	/* MSG_INTL(MSG_REJ_MISFLAG) */
701 	MSG_REJ_VERSION,	/* MSG_INTL(MSG_REJ_VERSION) */
702 	MSG_REJ_HAL,		/* MSG_INTL(MSG_REJ_HAL) */
703 	MSG_REJ_US3,		/* MSG_INTL(MSG_REJ_US3) */
704 	MSG_REJ_STR,		/* MSG_INTL(MSG_REJ_STR) */
705 	MSG_REJ_UNKFILE,	/* MSG_INTL(MSG_REJ_UNKFILE) */
706 	MSG_REJ_HWCAP_1,	/* MSG_INTL(MSG_REJ_HWCAP_1) */
707 };
708 
709 void
710 Dbg_file_rejected(Lm_list *lml, Rej_desc *rej)
711 {
712 	Conv_reject_desc_buf_t rej_buf;
713 
714 	if (DBG_NOTCLASS(DBG_C_FILES))
715 		return;
716 
717 	Dbg_util_nl(lml, DBG_NL_STD);
718 	dbg_print(lml, MSG_INTL(reject[rej->rej_type]), rej->rej_name ?
719 	    rej->rej_name : MSG_INTL(MSG_STR_UNKNOWN),
720 	    conv_reject_desc(rej, &rej_buf));
721 	Dbg_util_nl(lml, DBG_NL_STD);
722 }
723 
724 void
725 Dbg_file_reuse(Lm_list *lml, const char *nname, const char *oname)
726 {
727 	if (DBG_NOTCLASS(DBG_C_FILES))
728 		return;
729 
730 	dbg_print(lml, MSG_INTL(MSG_FIL_REUSE), nname, oname);
731 }
732 
733 void
734 Dbg_file_skip(Lm_list *lml, const char *oname, const char *nname)
735 {
736 	if (DBG_NOTCLASS(DBG_C_FILES))
737 		return;
738 
739 	if (oname && strcmp(nname, oname))
740 		dbg_print(lml, MSG_INTL(MSG_FIL_SKIP_1), nname, oname);
741 	else
742 		dbg_print(lml, MSG_INTL(MSG_FIL_SKIP_2), nname);
743 }
744 
745 void
746 Dbg_file_modified(Lm_list *lml, const char *obj, const char *oname,
747     const char *nname, int ofd, int nfd, Elf *oelf, Elf *nelf)
748 {
749 	const char	*str;
750 
751 	if (DBG_NOTCLASS(DBG_C_FILES | DBG_C_SUPPORT))
752 		return;
753 	if (DBG_NOTDETAIL())
754 		return;
755 
756 	Dbg_util_nl(lml, DBG_NL_STD);
757 	dbg_print(lml, MSG_INTL(MSG_FIL_MODIFIED), oname, obj);
758 
759 	if (nname != oname)
760 		dbg_print(lml, MSG_INTL(MSG_FIL_NAMECHANGE), nname);
761 	if (nfd != ofd) {
762 		if (nfd == -1)
763 			str = MSG_INTL(MSG_FIL_IGNORE);
764 		else
765 			str = MSG_ORIG(MSG_STR_EMPTY);
766 		dbg_print(lml, MSG_INTL(MSG_FIL_FDCHANGE), ofd, nfd, str);
767 	}
768 	if (nelf != oelf) {
769 		if (nelf == 0)
770 			str = MSG_INTL(MSG_FIL_IGNORE);
771 		else
772 			str = MSG_ORIG(MSG_STR_EMPTY);
773 		dbg_print(lml, MSG_INTL(MSG_FIL_ELFCHANGE), EC_NATPTR(oelf),
774 		    EC_NATPTR(nelf), str);
775 	}
776 	Dbg_util_nl(lml, DBG_NL_STD);
777 }
778 
779 void
780 Dbg_file_cleanup(Lm_list *lml, const char *name, Aliste lmco)
781 {
782 	if (DBG_NOTCLASS(DBG_C_FILES))
783 		return;
784 
785 	Dbg_util_nl(lml, DBG_NL_STD);
786 	dbg_print(lml, MSG_INTL(MSG_FIL_CLEANUP), name, EC_XWORD(lmco));
787 }
788