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