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