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